define(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] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.loaded = 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;
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "https://unpkg.com/ipysheet@0.1.0/dist/";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';
	
	// Entry point for the unpkg bundle containing custom model definitions.
	//
	// It differs from the notebook bundle in that it does not need to define a
	// dynamic baseURL for the static assets and may load some css that would
	// already be loaded by the notebook otherwise.
	
	// Export widget models and views, and the npm package version number.
	module.exports = __webpack_require__(1);
	module.exports['version'] = __webpack_require__(533).version;

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

	'use strict';
	
	var _base = __webpack_require__(2);
	
	var widgets = _interopRequireWildcard(_base);
	
	var _lodash = __webpack_require__(232);
	
	var _handsontable = __webpack_require__(233);
	
	var _handsontable2 = _interopRequireDefault(_handsontable);
	
	__webpack_require__(524);
	
	__webpack_require__(529);
	
	__webpack_require__(531);
	
	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 CellRangeModel = widgets.WidgetModel.extend({
	    defaults: function defaults() {
	        return (0, _lodash.extend)(CellRangeModel.__super__.defaults.call(this), {
	            _model_name: 'CellRangeModel',
	            _model_module: 'ipysheet',
	            _model_module_version: '0.1.0',
	            value: null,
	            row_start: 1,
	            column_start: 1,
	            row_end: 1,
	            column_end: 1,
	            type: null, //'text',
	            name: null,
	            style: {},
	            renderer: null,
	            read_only: false,
	            choice: null,
	            squeeze_row: true,
	            squeeze_column: true,
	            transpose: false,
	            format: '0.[000]'
	        });
	    }
	});
	
	var SheetModel = widgets.DOMWidgetModel.extend({
	    defaults: function defaults() {
	        return (0, _lodash.extend)(SheetModel.__super__.defaults.call(this), {
	            _model_name: 'SheetModel',
	            _view_name: 'SheetView',
	            _model_module: 'ipysheet',
	            _view_module: 'ipysheet',
	            _model_module_version: '0.1.0',
	            _view_module_version: '0.1.0',
	            rows: 3,
	            columns: 4,
	            data: [[]],
	            cells: [],
	            named_cells: {},
	            row_headers: true,
	            column_headers: true,
	            stretch_headers: 'all',
	            column_width: null
	        });
	    },
	    initialize: function initialize() {
	        var _this = this;
	
	        SheetModel.__super__.initialize.apply(this, arguments);
	        this.update_data_grid();
	        this._updating_grid = false;
	        window.last_sheet_model = this;
	        this.on('change:rows change:columns', this.update_data_grid, this);
	        this.on('change:cells', this.on_change_cells, this);
	        this.on('change:data', this.grid_to_cell, this);
	        (0, _lodash.each)(this.get('cells'), function (cell) {
	            return _this.cell_bind(cell);
	        });
	        this.cells_to_grid();
	    },
	    on_change_cells: function on_change_cells() {
	        console.log('change cells');
	        this._updating_grid = true;
	        try {
	            var previous_cells = this.previous('cells');
	            var cells = this.get('cells');
	            for (var i = 0; i < cells.length; i++) {
	                var cell = cells[i];
	                if (!(0, _lodash.includes)(previous_cells, cell)) {
	                    console.log('adding cell', cell);
	                    this.cell_bind(cell);
	                }
	            }
	            this.cells_to_grid();
	            //this.save_changes();
	        } finally {
	            this._updating_grid = false;
	        }
	        this.grid_to_cell();
	    },
	    cell_bind: function cell_bind(cell) {
	        //this.cell_to_grid(cell, false);
	        cell.on('change:value change:style change:type change:renderer change:read_only change:choice change:format', function () {
	            //this.cell_to_grid(cell, true);
	            this.cells_to_grid();
	        }, this);
	    },
	    cells_to_grid: function cells_to_grid() {
	        var _this2 = this;
	
	        (0, _lodash.each)(this.get('cells'), function (cell) {
	            return _this2.cell_to_grid(cell, false);
	        });
	        this.save_changes();
	    },
	    cell_to_grid: function cell_to_grid(cell, save) {
	        console.log('cell to grid', cell);
	        var data = (0, _lodash.cloneDeep)(this.get('data'));
	        for (var i = cell.get('row_start'); i <= cell.get('row_end'); i++) {
	            for (var j = cell.get('column_start'); j <= cell.get('column_end'); j++) {
	                var cell_row = i - cell.get('row_start');
	                var cell_col = j - cell.get('column_start');
	                var value = cell.get('value');
	                //console.log(cell.get('value'), i, j, cell_row, cell_col, ',', data.length, data[0].length, data, value)
	                //console.log(value[cell_row][cell_col])
	                var cell_data = data[i][j];
	                if (cell.get('transpose')) {
	                    if (!cell.get('squeeze_column')) value = value[cell_col];
	                    if (!cell.get('squeeze_row')) value = value[cell_row];
	                } else {
	                    if (!cell.get('squeeze_row')) value = value[cell_row];
	                    if (!cell.get('squeeze_column')) value = value[cell_col];
	                }
	                if (value != null) cell_data.value = value;
	                //console.log(i, j, cell.get('style'), value)
	                cell_data.options['type'] = cell.get('type') || cell_data.options['type'];
	                cell_data.options['style'] = (0, _lodash.extend)({}, cell_data.options['style'], cell.get('style'));
	                cell_data.options['renderer'] = cell.get('renderer') || cell_data.options['renderer'];
	                cell_data.options['readOnly'] = cell.get('read_only') || cell_data.options['readOnly'];
	                cell_data.options['source'] = cell.get('choice') || cell_data.options['source'];
	                cell_data.options['format'] = cell.get('format') || cell_data.options['format'];
	            }
	        }
	        this.set('data', data);
	        if (save) {
	            this.save_changes();
	        }
	    },
	    grid_to_cell: function grid_to_cell() {
	        if (this._updating_grid) {
	            console.log('grid to cell skipped');
	            return;
	        }
	        console.log('grid to cell', this._massive_update);
	        this._updating_grid = true;
	        try {
	            var data = this.get('data');
	            (0, _lodash.each)(this.get('cells'), function (cell) {
	                var rows = [];
	                for (var i = cell.get('row_start'); i <= cell.get('row_end'); i++) {
	                    var row = [];
	                    for (var j = cell.get('column_start'); j <= cell.get('column_end'); j++) {
	                        //var cell_row = i - cell.get('row_start');
	                        //var cell_col = j - cell.get('column_start');
	                        var cell_data = data[i][j];
	                        row.push(cell_data.value);
	                        /*cell.set('value', cell_data.value);
	                        cell.set('type', cell_data.options['type']);
	                        cell.set('style', cell_data.options['style']);
	                        cell.set('renderer', cell_data.options['renderer']);
	                        cell.set('read_only', cell_data.options['readOnly']);
	                        cell.set('choice', cell_data.options['source']);
	                        cell.set('format', cell_data.options['format']);*/
	                    }
	                    if (cell.get('squeeze_column')) {
	                        row = row[0];
	                    }
	                    rows.push(row);
	                }
	                if (cell.get('squeeze_row')) {
	                    rows = rows[0];
	                }
	                if (cell.get('transpose')) {
	                    cell.set('value', (0, _lodash.unzip)(rows));
	                } else {
	                    cell.set('value', rows);
	                }
	                cell.save_changes();
	            }, this);
	        } finally {
	            this._updating_grid = false;
	        }
	    },
	    update_data_grid: function update_data_grid() {
	        var _this3 = this;
	
	        // create a row x column array of arrays filled with null
	        var data = (0, _lodash.cloneDeep)(this.get('data')); // clone, otherwise backbone/underscore won't notice the change
	        var rows = this.get('rows');
	        var columns = this.get('columns');
	
	        var empty_cell = function empty_cell() {
	            return { value: null, options: {} };
	        };
	        var empty_row = function empty_row() {
	            return (0, _lodash.times)(_this3.get('columns'), empty_cell);
	        };
	        //console.log('data<', data)
	        if (rows < data.length) {
	            data = data.slice(0, rows);
	        } else if (rows > data.length) {
	            for (var i = data.length; i < rows; i++) {
	                data.push(empty_row());
	            }
	        }
	        for (var i = 0; i < rows; i++) {
	            var row = data[i];
	            if (columns < row.length) {
	                row = row.slice(0, columns);
	            } else if (columns > row.length) {
	                for (var j = row.length; j < columns; j++) {
	                    row.push(empty_cell());
	                }
	            }
	            data[i] = row;
	        }
	        //console.log('data>', data)
	        this.set('data', data);
	        this.save_changes();
	    }
	}, {
	    serializers: (0, _lodash.extend)({
	        cells: { deserialize: widgets.unpack_models }
	    }, widgets.DOMWidgetModel.serializers)
	});
	
	// go from 2d array with objects to a 2d grid containing just attribute `attr` from those objects
	var extract2d = function extract2d(grid, attr) {
	    return (0, _lodash.map)(grid, function (column) {
	        return (0, _lodash.map)(column, function (value) {
	            return value[attr];
	        });
	    });
	};
	// inverse of above
	var put_values2d = function put_values2d(grid, values) {
	    // TODO: the Math.min should not be needed, happens with the custom-build
	    for (var i = 0; i < Math.min(grid.length, values.length); i++) {
	        for (var j = 0; j < Math.min(grid[i].length, values[i].length); j++) {
	            grid[i][j].value = values[i][j];
	        }
	    }
	};
	
	// calls the original renderer and then applies custom styling
	_handsontable2.default.renderers.registerRenderer('styled', function customRenderer(hotInstance, td, row, column, prop, value, cellProperties) {
	    var name = cellProperties.original_renderer || cellProperties.type || 'text';
	    var original_renderer = _handsontable2.default.renderers.getRenderer(name);
	    original_renderer.apply(this, arguments);
	    (0, _lodash.each)(cellProperties.style, function (value, key) {
	        td.style[key] = value;
	    });
	});
	
	var testing = false;
	var setTesting = function setTesting() {
	    testing = true;
	};
	
	var SheetView = widgets.DOMWidgetView.extend({
	    render: function render() {
	        var _this4 = this;
	
	        this._refresh_requested = false;
	        /*
	        We debounce rendering of the table, since rendering can take quite some time, however that
	        makes unittesting difficult, since the results don't happend instanely. Maybe a better solution
	        is to use a deferred object.
	        */
	        if (testing) {
	            this.throttled_on_data_change = this._real_on_data_change;
	            this.throttled_render = this._real_table_render;
	        } else {
	            this.throttled_on_data_change = (0, _lodash.debounce)(function () {
	                return _this4._real_on_data_change();
	            }, 100);
	            this.throttled_render = (0, _lodash.debounce)(function () {
	                return _this4._real_table_render();
	            }, 100);
	        }
	        // 
	        //this.listenTo(this.model, 'change:data', this.on_data_change)
	        this.displayed.then(function () {
	            _this4._build_table().then(function (hot) {
	                _this4.hot = hot;
	                _handsontable2.default.hooks.add('afterChange', function () {
	                    return _this4._on_change();
	                }, _this4.hot);
	                _handsontable2.default.hooks.add('afterRemoveCol', function () {
	                    return _this4._on_change_grid();
	                }, _this4.hot);
	                _handsontable2.default.hooks.add('afterRemoveRow', function () {
	                    return _this4._on_change_grid();
	                }, _this4.hot);
	            });
	        });
	        window.last_sheet_view = this;
	        this.model.on('change:data', this.on_data_change, this);
	        this.model.on('change:column_headers change:row_headers', this._update_hot_settings, this);
	        this.model.on('change:stretch_headers change:column_width', this._update_hot_settings, this);
	    },
	    processPhosphorMessage: function processPhosphorMessage(msg) {
	        SheetView.__super__.processPhosphorMessage.apply(this, arguments);
	        switch (msg.type) {
	            case 'resize':
	            case 'after-show':
	                this.throttled_render();
	                break;
	        }
	    },
	    _build_table: function _build_table(options) {
	        var _this5 = this;
	
	        return Promise.resolve(new _handsontable2.default(this.el, (0, _lodash.extend)({}, options, {
	            data: this._get_cell_data(),
	            rowHeaders: true,
	            colHeaders: true,
	            cells: function cells() {
	                return _this5._cell.apply(_this5, arguments);
	            }
	        }, this._hot_settings())));
	    },
	
	    _update_hot_settings: function _update_hot_settings() {
	        console.log('update', this._hot_settings());
	        this.hot.updateSettings(this._hot_settings());
	    },
	    _hot_settings: function _hot_settings() {
	        return {
	            colHeaders: this.model.get('column_headers'),
	            rowHeaders: this.model.get('row_headers'),
	            stretchH: this.model.get('stretch_headers'),
	            colWidths: this.model.get('column_width') || undefined
	        };
	    },
	    _get_cell_data: function _get_cell_data() {
	        return extract2d(this.model.get('data'), 'value');
	    },
	    _cell: function _cell(row, col) {
	        var cellProperties = {};
	        var data = this.model.get('data');
	        if (row < data.length && col < data[row].length) {
	            (0, _lodash.extend)(cellProperties, data[row][col].options);
	        } else {
	            console.error('cell out of range');
	        }
	        if (cellProperties['type'] == null) delete cellProperties['type'];
	        if (cellProperties['style'] == null) delete cellProperties['style'];
	        if (cellProperties['source'] == null) delete cellProperties['source'];
	        if ('renderer' in cellProperties) cellProperties.original_renderer = cellProperties.renderer;
	        cellProperties.renderer = 'styled';
	        //console.log(row, col, prop, cellProperties)
	        return cellProperties;
	    },
	    _on_change_grid: function _on_change_grid(changes, source) {
	        var data = this.hot.getSourceDataArray();
	        console.log('table altered, make sure this is reflected in the model', data.length, data[0].length);
	        this.model.set({ 'rows': data.length, 'columns': data[0].length });
	        this.model.save_changes();
	    },
	    _on_change: function _on_change(changes, source) {
	        console.log('table altered...', changes, source);
	        //*
	        if (source == 'loadData') return; // ignore loadData
	        if (source == 'alter') {
	            console.log('table altered, make sure this is reflected in the model');
	            var data = this.hot.getSourceDataArray();
	            this.model.set({ 'rows': data.length, 'columns': data[0].length });
	            this.model.save_changes();
	            return;
	        }
	        //this.hot.validateCells()
	        //*
	        //this.hot.validateCells(_.bind(function(valid){
	        //    console.log('valid?', valid)
	        //    if(valid) {
	        var data = (0, _lodash.cloneDeep)(this.model.get('data'));
	        var value_data = this.hot.getSourceDataArray();
	        put_values2d(data, value_data);
	        this.model.set('data', (0, _lodash.cloneDeep)(data));
	        this.model.save_changes();
	        //    }
	        //}, this))
	        /**/
	    },
	    on_data_change: function on_data_change() {
	        this.throttled_on_data_change();
	        //this._real_on_data_change()
	    },
	    _real_on_data_change: function _real_on_data_change() {
	        var data = extract2d(this.model.get('data'), 'value');
	        var rows = data.length;
	        var cols = data[0].length;
	        var changed = false;
	        var rows_previous = this.hot.countRows();
	        var cols_previous = this.hot.countCols();
	        //*
	        if (rows > rows_previous) {
	            this.hot.alter('insert_row', rows - 1, rows - rows_previous);
	            changed = true;
	        }
	        if (rows < this.hot.countRows()) {
	            this.hot.alter('remove_row', rows - 1, rows_previous - rows);
	            changed = true;
	        }
	        if (cols > cols_previous) {
	            this.hot.alter('insert_col', cols - 1, cols - cols_previous);
	            changed = true;
	        }
	        if (cols < cols_previous) {
	            this.hot.alter('remove_col', cols - 1, cols_previous - cols);
	            changed = true;
	        } /**/
	
	        this.hot.loadData(data);
	        // if headers are not shows, loadData will make them show again, toggling
	        // will fix this (handsontable bug?)
	        this.hot.updateSettings({ colHeaders: true, rowHeaders: true });
	        this.hot.updateSettings({
	            colHeaders: this.model.get('column_headers'),
	            rowHeaders: this.model.get('row_headers')
	        });
	        this.throttled_render();
	        //this.hot.render()
	    },
	    set_cell: function set_cell(row, column, value) {
	        this.hot.setDataAtCell(row, column, value);
	    },
	    get_cell: function get_cell(row, column) {
	        return this.hot.getDataAtCell(row, column);
	    },
	    refresh_table: function refresh_table() {
	        var _this6 = this;
	
	        //this.hot.render()
	        if (!this._refresh_requested) {
	            this._refresh_requested = true;
	            requestAnimationFrame(function () {
	                return _this6._real_refresh_table();
	            }, this);
	        }
	    },
	    _real_table_render: function _real_table_render() {
	        this.hot.render();
	        this._refresh_requested = false;
	    }
	});
	
	module.exports = {
	    SheetModel: SheetModel,
	    SheetView: SheetView,
	    CellRangeModel: CellRangeModel,
	    Handsontable: _handsontable2.default,
	    setTesting: setTesting
	};

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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__webpack_require__(3));
	__export(__webpack_require__(166));
	__export(__webpack_require__(227));
	__export(__webpack_require__(228));
	__export(__webpack_require__(229));
	__export(__webpack_require__(230));
	__export(__webpack_require__(165));
	__export(__webpack_require__(4));
	__export(__webpack_require__(231));


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
	    return new (P || (P = Promise))(function (resolve, reject) {
	        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
	        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
	        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
	        step((generator = generator.apply(thisArg, _arguments || [])).next());
	    });
	};
	var __generator = (this && this.__generator) || function (thisArg, body) {
	    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
	    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
	    function verb(n) { return function (v) { return step([n, v]); }; }
	    function step(op) {
	        if (f) throw new TypeError("Generator is already executing.");
	        while (_) try {
	            if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
	            if (y = 0, t) op = [0, t.value];
	            switch (op[0]) {
	                case 0: case 1: t = op; break;
	                case 4: _.label++; return { value: op[1], done: false };
	                case 5: _.label++; y = op[1]; op = [0]; continue;
	                case 7: op = _.ops.pop(); _.trys.pop(); continue;
	                default:
	                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
	                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
	                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
	                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
	                    if (t[2]) _.ops.pop();
	                    _.trys.pop(); continue;
	            }
	            op = body.call(thisArg, _);
	        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
	        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
	    }
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils = __webpack_require__(4);
	var version_1 = __webpack_require__(165);
	var PROTOCOL_MAJOR_VERSION = version_1.PROTOCOL_VERSION.split('.', 1)[0];
	/**
	 * Manager abstract base class
	 */
	var ManagerBase = /** @class */ (function () {
	    function ManagerBase() {
	        /**
	         * The comm target name to register
	         */
	        this.comm_target_name = 'jupyter.widget';
	        /**
	         * Dictionary of model ids and model instance promises
	         */
	        this._models = Object.create(null);
	    }
	    /**
	     * Display a view for a particular model.
	     */
	    ManagerBase.prototype.display_model = function (msg, model, options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        return this.create_view(model, options).then(function (view) { return _this.display_view(msg, view, options); }).catch(utils.reject('Could not create view', true));
	    };
	    /**
	     * Modifies view options. Generally overloaded in custom widget manager
	     * implementations.
	     */
	    ManagerBase.prototype.setViewOptions = function (options) {
	        if (options === void 0) { options = {}; }
	        return options;
	    };
	    /**
	     * Creates a promise for a view of a given model
	     *
	     * Make sure the view creation is not out of order with
	     * any state updates.
	     */
	    ManagerBase.prototype.create_view = function (model, options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        var viewPromise = model.state_change = model.state_change.then(function () {
	            return _this.loadClass(model.get('_view_name'), model.get('_view_module'), model.get('_view_module_version')).then(function (ViewType) {
	                var view = new ViewType({
	                    model: model,
	                    options: _this.setViewOptions(options)
	                });
	                view.listenTo(model, 'destroy', view.remove);
	                return Promise.resolve(view.render()).then(function () { return view; });
	            }).catch(utils.reject('Could not create a view for model id ' + model.model_id, true));
	        });
	        var id = utils.uuid();
	        model.views[id] = viewPromise;
	        viewPromise.then(function (view) {
	            view.once('remove', function () { delete view.model.views[id]; }, _this);
	        });
	        return model.state_change;
	    };
	    /**
	     * callback handlers specific to a view
	     */
	    ManagerBase.prototype.callbacks = function (view) {
	        return {};
	    };
	    /**
	     * Get a promise for a model by model id.
	     */
	    ManagerBase.prototype.get_model = function (model_id) {
	        // TODO: Perhaps we should return a Promise.reject if the model is not
	        // found. Right now this isn't a true async function because it doesn't
	        // always return a promise.
	        return this._models[model_id];
	    };
	    /**
	     * Handle when a comm is opened.
	     */
	    ManagerBase.prototype.handle_comm_open = function (comm, msg) {
	        var protocolVersion = (msg.metadata || {}).version || '';
	        if (protocolVersion.split('.', 1)[0] !== PROTOCOL_MAJOR_VERSION) {
	            var error = "Wrong widget protocol version: received protocol version '" + protocolVersion + "', but was expecting major version '" + PROTOCOL_MAJOR_VERSION + "'";
	            console.error(error);
	            return Promise.reject(error);
	        }
	        var data = msg.content.data;
	        var buffer_paths = data.buffer_paths || [];
	        // Make sure the buffers are DataViews
	        var buffers = (msg.buffers || []).map(function (b) {
	            if (b instanceof DataView) {
	                return b;
	            }
	            else {
	                return new DataView(b instanceof ArrayBuffer ? b : b.buffer);
	            }
	        });
	        utils.put_buffers(data.state, buffer_paths, buffers);
	        return this.new_model({
	            model_name: data.state['_model_name'],
	            model_module: data.state['_model_module'],
	            model_module_version: data.state['_model_module_version'],
	            comm: comm
	        }, data.state).catch(utils.reject('Could not create a model.', true));
	    };
	    /**
	     * Create a comm and new widget model.
	     * @param  options - same options as new_model but comm is not
	     *                          required and additional options are available.
	     * @param  serialized_state - serialized model attributes.
	     */
	    ManagerBase.prototype.new_widget = function (options, serialized_state) {
	        var _this = this;
	        if (serialized_state === void 0) { serialized_state = {}; }
	        var commPromise;
	        // we check to make sure the view information is provided, to help catch
	        // backwards incompatibility errors.
	        if (options.view_name === undefined
	            || options.view_module === undefined
	            || options.view_module_version === undefined) {
	            return Promise.reject('new_widget(...) must be given view information in the options.');
	        }
	        // If no comm is provided, a new comm is opened for the jupyter.widget
	        // target.
	        if (options.comm) {
	            commPromise = Promise.resolve(options.comm);
	        }
	        else {
	            commPromise = this._create_comm(this.comm_target_name, options.model_id, {
	                state: {
	                    _model_module: options.model_module,
	                    _model_module_version: options.model_module_version,
	                    _model_name: options.model_name,
	                    _view_module: options.view_module,
	                    _view_module_version: options.view_module_version,
	                    _view_name: options.view_name
	                },
	            }, { version: version_1.PROTOCOL_VERSION });
	        }
	        // The options dictionary is copied since data will be added to it.
	        var options_clone = __assign({}, options);
	        // Create the model. In the case where the comm promise is rejected a
	        // comm-less model is still created with the required model id.
	        return commPromise.then(function (comm) {
	            // Comm Promise Resolved.
	            options_clone.comm = comm;
	            var widget_model = _this.new_model(options_clone, serialized_state);
	            return widget_model.then(function (model) {
	                model.sync('create', model);
	                return model;
	            });
	        }, function () {
	            // Comm Promise Rejected.
	            if (!options_clone.model_id) {
	                options_clone.model_id = utils.uuid();
	            }
	            return _this.new_model(options_clone, serialized_state);
	        });
	    };
	    ManagerBase.prototype.register_model = function (model_id, modelPromise) {
	        var _this = this;
	        this._models[model_id] = modelPromise;
	        modelPromise.then(function (model) {
	            model.once('comm:close', function () {
	                delete _this._models[model_id];
	            });
	        });
	    };
	    /**
	     * Create and return a promise for a new widget model
	     *
	     * @param options - the options for creating the model.
	     * @param serialized_state - attribute values for the model.
	     *
	     * @example
	     * widget_manager.new_model({
	     *      model_name: 'IntSlider',
	     *      model_module: '@jupyter-widgets/controls',
	     *      model_module_version: '1.0.0',
	     *      model_id: 'u-u-i-d'
	     * }).then((model) => { console.log('Create success!', model); },
	     *  (err) => {console.error(err)});
	     *
	     */
	    ManagerBase.prototype.new_model = function (options, serialized_state) {
	        if (serialized_state === void 0) { serialized_state = {}; }
	        return __awaiter(this, void 0, void 0, function () {
	            var model_id, modelPromise;
	            return __generator(this, function (_a) {
	                switch (_a.label) {
	                    case 0:
	                        if (options.model_id) {
	                            model_id = options.model_id;
	                        }
	                        else if (options.comm) {
	                            model_id = options.model_id = options.comm.comm_id;
	                        }
	                        else {
	                            throw new Error('Neither comm nor model_id provided in options object. At least one must exist.');
	                        }
	                        modelPromise = this._make_model(options, serialized_state);
	                        this.register_model(model_id, modelPromise);
	                        return [4 /*yield*/, modelPromise];
	                    case 1: return [2 /*return*/, _a.sent()];
	                }
	            });
	        });
	    };
	    ManagerBase.prototype._make_model = function (options, serialized_state) {
	        if (serialized_state === void 0) { serialized_state = {}; }
	        return __awaiter(this, void 0, void 0, function () {
	            var model_id, model_promise, ModelType, error_1, attributes, modelOptions, widget_model;
	            return __generator(this, function (_a) {
	                switch (_a.label) {
	                    case 0:
	                        model_id = options.model_id;
	                        model_promise = this.loadClass(options.model_name, options.model_module, options.model_module_version);
	                        _a.label = 1;
	                    case 1:
	                        _a.trys.push([1, 3, , 4]);
	                        return [4 /*yield*/, model_promise];
	                    case 2:
	                        ModelType = _a.sent();
	                        return [3 /*break*/, 4];
	                    case 3:
	                        error_1 = _a.sent();
	                        console.error('Could not instantiate widget');
	                        throw error_1;
	                    case 4:
	                        if (!ModelType) {
	                            throw new Error("Cannot find model module " + options.model_module + "@" + options.model_module_version + ", " + options.model_name);
	                        }
	                        return [4 /*yield*/, ModelType._deserialize_state(serialized_state, this)];
	                    case 5:
	                        attributes = _a.sent();
	                        modelOptions = {
	                            widget_manager: this,
	                            model_id: model_id,
	                            comm: options.comm,
	                        };
	                        widget_model = new ModelType(attributes, modelOptions);
	                        widget_model.name = options.model_name;
	                        widget_model.module = options.model_module;
	                        return [2 /*return*/, widget_model];
	                }
	            });
	        });
	    };
	    /**
	     * Close all widgets and empty the widget state.
	     * @return Promise that resolves when the widget state is cleared.
	     */
	    ManagerBase.prototype.clear_state = function () {
	        var _this = this;
	        return utils.resolvePromisesDict(this._models).then(function (models) {
	            Object.keys(models).forEach(function (id) { return models[id].close(); });
	            _this._models = {};
	        });
	    };
	    /**
	     * Asynchronously get the state of the widget manager.
	     *
	     * This includes all of the widget models, and follows the format given in
	     * the @jupyter-widgets/schema package.
	     *
	     * @param options - The options for what state to return.
	     * @returns Promise for a state dictionary
	     */
	    ManagerBase.prototype.get_state = function (options) {
	        if (options === void 0) { options = {}; }
	        return utils.resolvePromisesDict(this._models).then(function (models) {
	            var state = {};
	            Object.keys(models).forEach(function (model_id) {
	                var model = models[model_id];
	                var split = utils.remove_buffers(model.serialize(model.get_state(options.drop_defaults)));
	                var buffers = split.buffers.map(function (buffer, index) {
	                    return { data: utils.bufferToBase64(buffer), path: split.buffer_paths[index], encoding: 'base64' };
	                });
	                state[model_id] = {
	                    model_name: model.name,
	                    model_module: model.module,
	                    model_module_version: model.get('_model_module_version'),
	                    state: split.state
	                };
	                // To save space, only include the buffer key if we have buffers
	                if (buffers.length > 0) {
	                    state[model_id].buffers = buffers;
	                }
	            });
	            return { version_major: 2, version_minor: 0, state: state };
	        });
	    };
	    /**
	     * Set the widget manager state.
	     *
	     * @param state - a Javascript object conforming to the application/vnd.jupyter.widget-state+json spec.
	     *
	     * Reconstructs all of the widget models in the state, merges that with the
	     * current manager state, and then attempts to redisplay the widgets in the
	     * state.
	     */
	    ManagerBase.prototype.set_state = function (state) {
	        var _this = this;
	        // Check to make sure that it's the same version we are parsing.
	        if (!(state.version_major && state.version_major <= 2)) {
	            throw 'Unsupported widget state format';
	        }
	        var models = state.state;
	        // Recreate all the widget models for the given widget manager state.
	        var all_models = this._get_comm_info().then(function (live_comms) {
	            return Promise.all(Object.keys(models).map(function (model_id) {
	                // First put back the binary buffers
	                var decode = { 'base64': utils.base64ToBuffer, 'hex': utils.hexToBuffer };
	                var model = models[model_id];
	                var modelState = model.state;
	                if (model.buffers) {
	                    var bufferPaths = model.buffers.map(function (b) { return b.path; });
	                    // put_buffers expects buffers to be DataViews
	                    var buffers = model.buffers.map(function (b) { return new DataView(decode[b.encoding](b.data)); });
	                    utils.put_buffers(model.state, bufferPaths, buffers);
	                }
	                // If the model has already been created, set its state and then
	                // return it.
	                if (_this._models[model_id]) {
	                    return _this._models[model_id].then(function (model) {
	                        // deserialize state
	                        return model.constructor._deserialize_state(modelState || {}, _this).then(function (attributes) {
	                            model.set_state(attributes);
	                            return model;
	                        });
	                    });
	                }
	                var modelCreate = {
	                    model_id: model_id,
	                    model_name: model.model_name,
	                    model_module: model.model_module,
	                    model_module_version: model.model_module_version
	                };
	                if (live_comms.hasOwnProperty(model_id)) {
	                    // This connects to an existing comm if it exists, and
	                    // should *not* send a comm open message.
	                    return _this._create_comm(_this.comm_target_name, model_id).then(function (comm) {
	                        modelCreate.comm = comm;
	                        return _this.new_model(modelCreate);
	                    });
	                }
	                else {
	                    return _this.new_model(modelCreate, modelState);
	                }
	            }));
	        });
	        return all_models;
	    };
	    /**
	     * Disconnect the widget manager from the kernel, setting each model's comm
	     * as dead.
	     */
	    ManagerBase.prototype.disconnect = function () {
	        var _this = this;
	        Object.keys(this._models).forEach(function (i) {
	            _this._models[i].then(function (model) { model.comm_live = false; });
	        });
	    };
	    return ManagerBase;
	}());
	exports.ManagerBase = ManagerBase;


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var base64_js_1 = __webpack_require__(5);
	var coreutils_1 = __webpack_require__(6);
	var _isEqual = __webpack_require__(73);
	var isPlainObject = __webpack_require__(163);
	/**
	 * Find all strings in the first argument that are not in the second.
	 */
	function difference(a, b) {
	    return a.filter(function (v) { return b.indexOf(v) === -1; });
	}
	exports.difference = difference;
	/**
	 * Compare two objects deeply to see if they are equal.
	 */
	function isEqual(a, b) {
	    return _isEqual(a, b);
	}
	exports.isEqual = isEqual;
	/**
	 * A polyfill for Object.assign
	 *
	 * This is from code that Typescript 2.4 generates for a polyfill.
	 */
	exports.assign = Object.assign || function (t) {
	    for (var i = 1; i < arguments.length; i++) {
	        var s = arguments[i];
	        for (var p in s) {
	            if (Object.prototype.hasOwnProperty.call(s, p)) {
	                t[p] = s[p];
	            }
	        }
	    }
	    return t;
	};
	/**
	 * Generate a UUID
	 *
	 * http://www.ietf.org/rfc/rfc4122.txt
	 */
	function uuid() {
	    return coreutils_1.UUID.uuid4();
	}
	exports.uuid = uuid;
	/**
	 * Wrappable Error class
	 *
	 * The Error class doesn't actually act on `this`.  Instead it always
	 * returns a new instance of Error.  Here we capture that instance so we
	 * can apply it's properties to `this`.
	 */
	var WrappedError = /** @class */ (function (_super) {
	    __extends(WrappedError, _super);
	    function WrappedError(message, error) {
	        var _this = _super.call(this, message) || this;
	        console.warn('WrappedError has been deprecated!');
	        // Keep a stack of the original error messages.
	        if (error instanceof WrappedError) {
	            _this.error_stack = error.error_stack;
	        }
	        else {
	            _this.error_stack = [error];
	        }
	        _this.error_stack.push(_this);
	        return _this;
	    }
	    return WrappedError;
	}(Error));
	exports.WrappedError = WrappedError;
	/**
	 * Resolve a promiseful dictionary.
	 * Returns a single Promise.
	 */
	function resolvePromisesDict(d) {
	    var keys = Object.keys(d);
	    var values = [];
	    keys.forEach(function (key) {
	        values.push(d[key]);
	    });
	    return Promise.all(values).then(function (v) {
	        d = {};
	        for (var i = 0; i < keys.length; i++) {
	            d[keys[i]] = v[i];
	        }
	        return d;
	    });
	}
	exports.resolvePromisesDict = resolvePromisesDict;
	/**
	 * Creates a wrappable Promise rejection function.
	 *
	 * Creates a function that logs an error message before rethrowing
	 * the original error that caused the promise to reject.
	 */
	function reject(message, log) {
	    return function promiseRejection(error) {
	        if (log) {
	            console.error(new Error(message));
	        }
	        throw error;
	    };
	}
	exports.reject = reject;
	/**
	 * Takes an object 'state' and fills in buffer[i] at 'path' buffer_paths[i]
	 * where buffer_paths[i] is a list indicating where in the object buffer[i] should
	 * be placed
	 * Example: state = {a: 1, b: {}, c: [0, null]}
	 * buffers = [array1, array2]
	 * buffer_paths = [['b', 'data'], ['c', 1]]
	 * Will lead to {a: 1, b: {data: array1}, c: [0, array2]}
	 */
	function put_buffers(state, buffer_paths, buffers) {
	    for (var i = 0; i < buffer_paths.length; i++) {
	        var buffer_path = buffer_paths[i];
	        // say we want to set state[x][y][z] = buffers[i]
	        var obj = state;
	        // we first get obj = state[x][y]
	        for (var j = 0; j < buffer_path.length - 1; j++) {
	            obj = obj[buffer_path[j]];
	        }
	        // and then set: obj[z] = buffers[i]
	        obj[buffer_path[buffer_path.length - 1]] = buffers[i];
	    }
	}
	exports.put_buffers = put_buffers;
	/**
	 * The inverse of put_buffers, return an objects with the new state where all buffers(ArrayBuffer)
	 * are removed. If a buffer is a member of an object, that object is cloned, and the key removed. If a buffer
	 * is an element of an array, that array is cloned, and the element is set to null.
	 * See put_buffers for the meaning of buffer_paths
	 * Returns an object with the new state (.state) an array with paths to the buffers (.buffer_paths),
	 * and the buffers associated to those paths (.buffers).
	 */
	function remove_buffers(state) {
	    var buffers = [];
	    var buffer_paths = [];
	    // if we need to remove an object from a list, we need to clone that list, otherwise we may modify
	    // the internal state of the widget model
	    // however, we do not want to clone everything, for performance
	    function remove(obj, path) {
	        if (obj.toJSON) {
	            // We need to get the JSON form of the object before recursing.
	            // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior
	            obj = obj.toJSON();
	        }
	        if (Array.isArray(obj)) {
	            var is_cloned = false;
	            for (var i = 0; i < obj.length; i++) {
	                var value = obj[i];
	                if (value) {
	                    if (value.buffer instanceof ArrayBuffer || value instanceof ArrayBuffer) {
	                        if (!is_cloned) {
	                            obj = obj.slice();
	                            is_cloned = true;
	                        }
	                        buffers.push(value instanceof ArrayBuffer ? value : value.buffer);
	                        buffer_paths.push(path.concat([i]));
	                        // easier to just keep the array, but clear the entry, otherwise we have to think
	                        // about array length, much easier this way
	                        obj[i] = null;
	                    }
	                    else {
	                        var new_value = remove(value, path.concat([i]));
	                        // only assigned when the value changes, we may serialize objects that don't support assignment
	                        if (new_value !== value) {
	                            if (!is_cloned) {
	                                obj = obj.slice();
	                                is_cloned = true;
	                            }
	                            obj[i] = new_value;
	                        }
	                    }
	                }
	            }
	        }
	        else if (isPlainObject(obj)) {
	            for (var key in obj) {
	                var is_cloned = false;
	                if (obj.hasOwnProperty(key)) {
	                    var value = obj[key];
	                    if (value) {
	                        if (value.buffer instanceof ArrayBuffer || value instanceof ArrayBuffer) {
	                            if (!is_cloned) {
	                                obj = __assign({}, obj);
	                                is_cloned = true;
	                            }
	                            buffers.push(value instanceof ArrayBuffer ? value : value.buffer);
	                            buffer_paths.push(path.concat([key]));
	                            delete obj[key]; // for objects/dicts we just delete them
	                        }
	                        else {
	                            var new_value = remove(value, path.concat([key]));
	                            // only assigned when the value changes, we may serialize objects that don't support assignment
	                            if (new_value !== value) {
	                                if (!is_cloned) {
	                                    obj = __assign({}, obj);
	                                    is_cloned = true;
	                                }
	                                obj[key] = new_value;
	                            }
	                        }
	                    }
	                }
	            }
	        }
	        return obj;
	    }
	    var new_state = remove(state, []);
	    return { state: new_state, buffers: buffers, buffer_paths: buffer_paths };
	}
	exports.remove_buffers = remove_buffers;
	var hexTable = [
	    '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0A', '0B', '0C', '0D', '0E', '0F',
	    '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1A', '1B', '1C', '1D', '1E', '1F',
	    '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2A', '2B', '2C', '2D', '2E', '2F',
	    '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3A', '3B', '3C', '3D', '3E', '3F',
	    '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4A', '4B', '4C', '4D', '4E', '4F',
	    '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5A', '5B', '5C', '5D', '5E', '5F',
	    '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6A', '6B', '6C', '6D', '6E', '6F',
	    '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7A', '7B', '7C', '7D', '7E', '7F',
	    '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8A', '8B', '8C', '8D', '8E', '8F',
	    '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9A', '9B', '9C', '9D', '9E', '9F',
	    'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF',
	    'B0', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'BA', 'BB', 'BC', 'BD', 'BE', 'BF',
	    'C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'CA', 'CB', 'CC', 'CD', 'CE', 'CF',
	    'D0', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'DA', 'DB', 'DC', 'DD', 'DE', 'DF',
	    'E0', 'E1', 'E2', 'E3', 'E4', 'E5', 'E6', 'E7', 'E8', 'E9', 'EA', 'EB', 'EC', 'ED', 'EE', 'EF',
	    'F0', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'FA', 'FB', 'FC', 'FD', 'FE', 'FF'
	];
	/**
	 * Convert an ArrayBuffer to a hex string.
	 */
	function bufferToHex(buffer) {
	    var x = new Uint8Array(buffer);
	    var s = [];
	    for (var i = 0; i < x.length; i++) {
	        s.push(hexTable[x[i]]);
	    }
	    return s.join('');
	}
	exports.bufferToHex = bufferToHex;
	/**
	 * Convert a hex string to an ArrayBuffer.
	 */
	function hexToBuffer(hex) {
	    var x = new Uint8Array(hex.length / 2);
	    for (var i = 0; i < hex.length; i += 2) {
	        x[i / 2] = parseInt(hex.slice(i, i + 2), 16);
	    }
	    return x.buffer;
	}
	exports.hexToBuffer = hexToBuffer;
	/**
	 * Convert an ArrayBuffer to a base64 string.
	 */
	function bufferToBase64(buffer) {
	    return base64_js_1.fromByteArray(new Uint8Array(buffer));
	}
	exports.bufferToBase64 = bufferToBase64;
	/**
	 * Convert a base64 string to an ArrayBuffer.
	 */
	function base64ToBuffer(base64) {
	    return base64_js_1.toByteArray(base64).buffer;
	}
	exports.base64ToBuffer = base64ToBuffer;


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

	'use strict'
	
	exports.byteLength = byteLength
	exports.toByteArray = toByteArray
	exports.fromByteArray = fromByteArray
	
	var lookup = []
	var revLookup = []
	var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
	
	var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
	for (var i = 0, len = code.length; i < len; ++i) {
	  lookup[i] = code[i]
	  revLookup[code.charCodeAt(i)] = i
	}
	
	revLookup['-'.charCodeAt(0)] = 62
	revLookup['_'.charCodeAt(0)] = 63
	
	function placeHoldersCount (b64) {
	  var len = b64.length
	  if (len % 4 > 0) {
	    throw new Error('Invalid string. Length must be a multiple of 4')
	  }
	
	  // the number of equal signs (place holders)
	  // if there are two placeholders, than the two characters before it
	  // represent one byte
	  // if there is only one, then the three characters before it represent 2 bytes
	  // this is just a cheap hack to not do indexOf twice
	  return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
	}
	
	function byteLength (b64) {
	  // base64 is 4/3 + up to two characters of the original data
	  return (b64.length * 3 / 4) - placeHoldersCount(b64)
	}
	
	function toByteArray (b64) {
	  var i, l, tmp, placeHolders, arr
	  var len = b64.length
	  placeHolders = placeHoldersCount(b64)
	
	  arr = new Arr((len * 3 / 4) - placeHolders)
	
	  // if there are placeholders, only get up to the last complete 4 chars
	  l = placeHolders > 0 ? len - 4 : len
	
	  var L = 0
	
	  for (i = 0; i < l; i += 4) {
	    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
	    arr[L++] = (tmp >> 16) & 0xFF
	    arr[L++] = (tmp >> 8) & 0xFF
	    arr[L++] = tmp & 0xFF
	  }
	
	  if (placeHolders === 2) {
	    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
	    arr[L++] = tmp & 0xFF
	  } else if (placeHolders === 1) {
	    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
	    arr[L++] = (tmp >> 8) & 0xFF
	    arr[L++] = tmp & 0xFF
	  }
	
	  return arr
	}
	
	function tripletToBase64 (num) {
	  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
	}
	
	function encodeChunk (uint8, start, end) {
	  var tmp
	  var output = []
	  for (var i = start; i < end; i += 3) {
	    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
	    output.push(tripletToBase64(tmp))
	  }
	  return output.join('')
	}
	
	function fromByteArray (uint8) {
	  var tmp
	  var len = uint8.length
	  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
	  var output = ''
	  var parts = []
	  var maxChunkLength = 16383 // must be multiple of 3
	
	  // go through the array every three bytes, we'll deal with trailing stuff later
	  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
	    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
	  }
	
	  // pad the end with zeros, but make sure to not forget the extra bytes
	  if (extraBytes === 1) {
	    tmp = uint8[len - 1]
	    output += lookup[tmp >> 2]
	    output += lookup[(tmp << 4) & 0x3F]
	    output += '=='
	  } else if (extraBytes === 2) {
	    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
	    output += lookup[tmp >> 10]
	    output += lookup[(tmp >> 4) & 0x3F]
	    output += lookup[(tmp << 2) & 0x3F]
	    output += '='
	  }
	
	  parts.push(output)
	
	  return parts.join('')
	}


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

	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__webpack_require__(7));
	__export(__webpack_require__(8));
	__export(__webpack_require__(9));
	__export(__webpack_require__(10));
	__export(__webpack_require__(71));
	__export(__webpack_require__(72));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for JSON-specific functions.
	 */
	var JSONExt;
	(function (JSONExt) {
	    /**
	     * A shared frozen empty JSONObject
	     */
	    JSONExt.emptyObject = Object.freeze({});
	    /**
	     * A shared frozen empty JSONArray
	     */
	    JSONExt.emptyArray = Object.freeze([]);
	    /**
	     * Test whether a JSON value is a primitive.
	     *
	     * @param value - The JSON value of interest.
	     *
	     * @returns `true` if the value is a primitive,`false` otherwise.
	     */
	    function isPrimitive(value) {
	        return (value === null ||
	            typeof value === 'boolean' ||
	            typeof value === 'number' ||
	            typeof value === 'string');
	    }
	    JSONExt.isPrimitive = isPrimitive;
	    function isArray(value) {
	        return Array.isArray(value);
	    }
	    JSONExt.isArray = isArray;
	    function isObject(value) {
	        return !isPrimitive(value) && !isArray(value);
	    }
	    JSONExt.isObject = isObject;
	    /**
	     * Compare two JSON values for deep equality.
	     *
	     * @param first - The first JSON value of interest.
	     *
	     * @param second - The second JSON value of interest.
	     *
	     * @returns `true` if the values are equivalent, `false` otherwise.
	     */
	    function deepEqual(first, second) {
	        // Check referential and primitive equality first.
	        if (first === second) {
	            return true;
	        }
	        // If one is a primitive, the `===` check ruled out the other.
	        if (isPrimitive(first) || isPrimitive(second)) {
	            return false;
	        }
	        // Test whether they are arrays.
	        var a1 = isArray(first);
	        var a2 = isArray(second);
	        // Bail if the types are different.
	        if (a1 !== a2) {
	            return false;
	        }
	        // If they are both arrays, compare them.
	        if (a1 && a2) {
	            return deepArrayEqual(first, second);
	        }
	        // At this point, they must both be objects.
	        return deepObjectEqual(first, second);
	    }
	    JSONExt.deepEqual = deepEqual;
	    /**
	     * Create a deep copy of a JSON value.
	     *
	     * @param value - The JSON value to copy.
	     *
	     * @returns A deep copy of the given JSON value.
	     */
	    function deepCopy(value) {
	        // Do nothing for primitive values.
	        if (isPrimitive(value)) {
	            return value;
	        }
	        // Deep copy an array.
	        if (isArray(value)) {
	            return deepArrayCopy(value);
	        }
	        // Deep copy an object.
	        return deepObjectCopy(value);
	    }
	    JSONExt.deepCopy = deepCopy;
	    /**
	     * Compare two JSON arrays for deep equality.
	     */
	    function deepArrayEqual(first, second) {
	        // Check referential equality first.
	        if (first === second) {
	            return true;
	        }
	        // Test the arrays for equal length.
	        if (first.length !== second.length) {
	            return false;
	        }
	        // Compare the values for equality.
	        for (var i = 0, n = first.length; i < n; ++i) {
	            if (!deepEqual(first[i], second[i])) {
	                return false;
	            }
	        }
	        // At this point, the arrays are equal.
	        return true;
	    }
	    /**
	     * Compare two JSON objects for deep equality.
	     */
	    function deepObjectEqual(first, second) {
	        // Check referential equality first.
	        if (first === second) {
	            return true;
	        }
	        // Check for the first object's keys in the second object.
	        for (var key in first) {
	            if (!(key in second)) {
	                return false;
	            }
	        }
	        // Check for the second object's keys in the first object.
	        for (var key in second) {
	            if (!(key in first)) {
	                return false;
	            }
	        }
	        // Compare the values for equality.
	        for (var key in first) {
	            if (!deepEqual(first[key], second[key])) {
	                return false;
	            }
	        }
	        // At this point, the objects are equal.
	        return true;
	    }
	    /**
	     * Create a deep copy of a JSON array.
	     */
	    function deepArrayCopy(value) {
	        var result = new Array(value.length);
	        for (var i = 0, n = value.length; i < n; ++i) {
	            result[i] = deepCopy(value[i]);
	        }
	        return result;
	    }
	    /**
	     * Create a deep copy of a JSON object.
	     */
	    function deepObjectCopy(value) {
	        var result = {};
	        for (var key in value) {
	            result[key] = deepCopy(value[key]);
	        }
	        return result;
	    }
	})(JSONExt = exports.JSONExt || (exports.JSONExt = {}));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * An object which stores MIME data for general application use.
	 *
	 * #### Notes
	 * This class does not attempt to enforce "correctness" of MIME types
	 * and their associated data. Since this class is designed to transfer
	 * arbitrary data and objects within the same application, it assumes
	 * that the user provides correct and accurate data.
	 */
	var MimeData = (function () {
	    function MimeData() {
	        this._types = [];
	        this._values = [];
	    }
	    /**
	     * Get an array of the MIME types contained within the dataset.
	     *
	     * @returns A new array of the MIME types, in order of insertion.
	     */
	    MimeData.prototype.types = function () {
	        return this._types.slice();
	    };
	    /**
	     * Test whether the dataset has an entry for the given type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * @returns `true` if the dataset contains a value for the given
	     *   MIME type, `false` otherwise.
	     */
	    MimeData.prototype.hasData = function (mime) {
	        return this._types.indexOf(mime) !== -1;
	    };
	    /**
	     * Get the data value for the given MIME type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * @returns The value for the given MIME type, or `undefined` if
	     *   the dataset does not contain a value for the type.
	     */
	    MimeData.prototype.getData = function (mime) {
	        var i = this._types.indexOf(mime);
	        return i !== -1 ? this._values[i] : undefined;
	    };
	    /**
	     * Set the data value for the given MIME type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * @param data - The data value for the given MIME type.
	     *
	     * #### Notes
	     * This will overwrite any previous entry for the MIME type.
	     */
	    MimeData.prototype.setData = function (mime, data) {
	        this.clearData(mime);
	        this._types.push(mime);
	        this._values.push(data);
	    };
	    /**
	     * Remove the data entry for the given MIME type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * #### Notes
	     * This is a no-op if there is no entry for the given MIME type.
	     */
	    MimeData.prototype.clearData = function (mime) {
	        var i = this._types.indexOf(mime);
	        if (i !== -1) {
	            this._types.splice(i, 1);
	            this._values.splice(i, 1);
	        }
	    };
	    /**
	     * Remove all data entries from the dataset.
	     */
	    MimeData.prototype.clear = function () {
	        this._types.length = 0;
	        this._values.length = 0;
	    };
	    return MimeData;
	}());
	exports.MimeData = MimeData;


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A class which wraps a promise into a delegate object.
	 *
	 * #### Notes
	 * This class is useful when the logic to resolve or reject a promise
	 * cannot be defined at the point where the promise is created.
	 */
	var PromiseDelegate = (function () {
	    /**
	     * Construct a new promise delegate.
	     */
	    function PromiseDelegate() {
	        var _this = this;
	        this.promise = new Promise(function (resolve, reject) {
	            _this._resolve = resolve;
	            _this._reject = reject;
	        });
	    }
	    /**
	     * Resolve the wrapped promise with the given value.
	     *
	     * @param value - The value to use for resolving the promise.
	     */
	    PromiseDelegate.prototype.resolve = function (value) {
	        var resolve = this._resolve;
	        resolve(value);
	    };
	    /**
	     * Reject the wrapped promise with the given value.
	     *
	     * @reason - The reason for rejecting the promise.
	     */
	    PromiseDelegate.prototype.reject = function (reason) {
	        var reject = this._reject;
	        reject(reason);
	    };
	    return PromiseDelegate;
	}());
	exports.PromiseDelegate = PromiseDelegate;


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for random number related functionality.
	 */
	var Random;
	(function (Random) {
	    /**
	     * A function which generates random bytes.
	     *
	     * @param buffer - The `Uint8Array` to fill with random bytes.
	     *
	     * #### Notes
	     * A cryptographically strong random number generator will be used if
	     * available. Otherwise, `Math.random` will be used as a fallback for
	     * randomness.
	     *
	     * The following RNGs are supported, listed in order of precedence:
	     *   - `window.crypto.getRandomValues`
	     *   - `window.msCrypto.getRandomValues`
	     *   - `require('crypto').randomFillSync
	     *   - `require('crypto').randomBytes
	     *   - `Math.random`
	     */
	    Random.getRandomValues = (function () {
	        // Look up the crypto module if available.
	        var crypto = ((typeof window !== 'undefined' && (window.crypto || window.msCrypto)) ||
	            ("function" !== 'undefined' && __webpack_require__(11)) || null);
	        // Modern browsers and IE 11
	        if (crypto && typeof crypto.getRandomValues === 'function') {
	            return function getRandomValues(buffer) {
	                return crypto.getRandomValues(buffer);
	            };
	        }
	        // Node 7+
	        if (crypto && typeof crypto.randomFillSync === 'function') {
	            return function getRandomValues(buffer) {
	                return crypto.randomFillSync(buffer);
	            };
	        }
	        // Node 0.10+
	        if (crypto && typeof crypto.randomBytes === 'function') {
	            return function getRandomValues(buffer) {
	                var bytes = crypto.randomBytes(buffer.length);
	                for (var i = 0, n = bytes.length; i < n; ++i) {
	                    buffer[i] = bytes[i];
	                }
	            };
	        }
	        // Fallback
	        return function getRandomValues(buffer) {
	            var value = 0;
	            for (var i = 0, n = buffer.length; i < n; ++i) {
	                if (i % 4 === 0) {
	                    value = Math.random() * 0xFFFFFFFF >>> 0;
	                }
	                buffer[i] = value & 0xFF;
	                value >>>= 8;
	            }
	        };
	    })();
	})(Random = exports.Random || (exports.Random = {}));


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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var rng = __webpack_require__(15)
	
	function error () {
	  var m = [].slice.call(arguments).join(' ')
	  throw new Error([
	    m,
	    'we accept pull requests',
	    'http://github.com/dominictarr/crypto-browserify'
	    ].join('\n'))
	}
	
	exports.createHash = __webpack_require__(17)
	
	exports.createHmac = __webpack_require__(30)
	
	exports.randomBytes = function(size, callback) {
	  if (callback && callback.call) {
	    try {
	      callback.call(this, undefined, new Buffer(rng(size)))
	    } catch (err) { callback(err) }
	  } else {
	    return new Buffer(rng(size))
	  }
	}
	
	function each(a, f) {
	  for(var i in a)
	    f(a[i], i)
	}
	
	exports.getHashes = function () {
	  return ['sha1', 'sha256', 'sha512', 'md5', 'rmd160']
	}
	
	var p = __webpack_require__(31)(exports)
	exports.pbkdf2 = p.pbkdf2
	exports.pbkdf2Sync = p.pbkdf2Sync
	__webpack_require__(33)(exports, module.exports);
	
	// the least I can do is make error messages for the rest of the node.js/crypto api.
	each(['createCredentials'
	, 'createSign'
	, 'createVerify'
	, 'createDiffieHellman'
	], function (name) {
	  exports[name] = function () {
	    error('sorry,', name, 'is not implemented yet')
	  }
	})
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(global) {/*!
	 * The buffer module from node.js, for the browser.
	 *
	 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
	 * @license  MIT
	 */
	/* eslint-disable no-proto */
	
	'use strict'
	
	var base64 = __webpack_require__(5)
	var ieee754 = __webpack_require__(13)
	var isArray = __webpack_require__(14)
	
	exports.Buffer = Buffer
	exports.SlowBuffer = SlowBuffer
	exports.INSPECT_MAX_BYTES = 50
	
	/**
	 * If `Buffer.TYPED_ARRAY_SUPPORT`:
	 *   === true    Use Uint8Array implementation (fastest)
	 *   === false   Use Object implementation (most compatible, even IE6)
	 *
	 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
	 * Opera 11.6+, iOS 4.2+.
	 *
	 * Due to various browser bugs, sometimes the Object implementation will be used even
	 * when the browser supports typed arrays.
	 *
	 * Note:
	 *
	 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
	 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
	 *
	 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
	 *
	 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
	 *     incorrect length in some situations.
	
	 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
	 * get the Object implementation, which is slower but behaves correctly.
	 */
	Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
	  ? global.TYPED_ARRAY_SUPPORT
	  : typedArraySupport()
	
	/*
	 * Export kMaxLength after typed array support is determined.
	 */
	exports.kMaxLength = kMaxLength()
	
	function typedArraySupport () {
	  try {
	    var arr = new Uint8Array(1)
	    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
	    return arr.foo() === 42 && // typed array instances can be augmented
	        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
	        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
	  } catch (e) {
	    return false
	  }
	}
	
	function kMaxLength () {
	  return Buffer.TYPED_ARRAY_SUPPORT
	    ? 0x7fffffff
	    : 0x3fffffff
	}
	
	function createBuffer (that, length) {
	  if (kMaxLength() < length) {
	    throw new RangeError('Invalid typed array length')
	  }
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    // Return an augmented `Uint8Array` instance, for best performance
	    that = new Uint8Array(length)
	    that.__proto__ = Buffer.prototype
	  } else {
	    // Fallback: Return an object instance of the Buffer class
	    if (that === null) {
	      that = new Buffer(length)
	    }
	    that.length = length
	  }
	
	  return that
	}
	
	/**
	 * The Buffer constructor returns instances of `Uint8Array` that have their
	 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
	 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
	 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
	 * returns a single octet.
	 *
	 * The `Uint8Array` prototype remains unmodified.
	 */
	
	function Buffer (arg, encodingOrOffset, length) {
	  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
	    return new Buffer(arg, encodingOrOffset, length)
	  }
	
	  // Common case.
	  if (typeof arg === 'number') {
	    if (typeof encodingOrOffset === 'string') {
	      throw new Error(
	        'If encoding is specified then the first argument must be a string'
	      )
	    }
	    return allocUnsafe(this, arg)
	  }
	  return from(this, arg, encodingOrOffset, length)
	}
	
	Buffer.poolSize = 8192 // not used by this implementation
	
	// TODO: Legacy, not needed anymore. Remove in next major version.
	Buffer._augment = function (arr) {
	  arr.__proto__ = Buffer.prototype
	  return arr
	}
	
	function from (that, value, encodingOrOffset, length) {
	  if (typeof value === 'number') {
	    throw new TypeError('"value" argument must not be a number')
	  }
	
	  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
	    return fromArrayBuffer(that, value, encodingOrOffset, length)
	  }
	
	  if (typeof value === 'string') {
	    return fromString(that, value, encodingOrOffset)
	  }
	
	  return fromObject(that, value)
	}
	
	/**
	 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
	 * if value is a number.
	 * Buffer.from(str[, encoding])
	 * Buffer.from(array)
	 * Buffer.from(buffer)
	 * Buffer.from(arrayBuffer[, byteOffset[, length]])
	 **/
	Buffer.from = function (value, encodingOrOffset, length) {
	  return from(null, value, encodingOrOffset, length)
	}
	
	if (Buffer.TYPED_ARRAY_SUPPORT) {
	  Buffer.prototype.__proto__ = Uint8Array.prototype
	  Buffer.__proto__ = Uint8Array
	  if (typeof Symbol !== 'undefined' && Symbol.species &&
	      Buffer[Symbol.species] === Buffer) {
	    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
	    Object.defineProperty(Buffer, Symbol.species, {
	      value: null,
	      configurable: true
	    })
	  }
	}
	
	function assertSize (size) {
	  if (typeof size !== 'number') {
	    throw new TypeError('"size" argument must be a number')
	  } else if (size < 0) {
	    throw new RangeError('"size" argument must not be negative')
	  }
	}
	
	function alloc (that, size, fill, encoding) {
	  assertSize(size)
	  if (size <= 0) {
	    return createBuffer(that, size)
	  }
	  if (fill !== undefined) {
	    // Only pay attention to encoding if it's a string. This
	    // prevents accidentally sending in a number that would
	    // be interpretted as a start offset.
	    return typeof encoding === 'string'
	      ? createBuffer(that, size).fill(fill, encoding)
	      : createBuffer(that, size).fill(fill)
	  }
	  return createBuffer(that, size)
	}
	
	/**
	 * Creates a new filled Buffer instance.
	 * alloc(size[, fill[, encoding]])
	 **/
	Buffer.alloc = function (size, fill, encoding) {
	  return alloc(null, size, fill, encoding)
	}
	
	function allocUnsafe (that, size) {
	  assertSize(size)
	  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) {
	    for (var i = 0; i < size; ++i) {
	      that[i] = 0
	    }
	  }
	  return that
	}
	
	/**
	 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
	 * */
	Buffer.allocUnsafe = function (size) {
	  return allocUnsafe(null, size)
	}
	/**
	 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
	 */
	Buffer.allocUnsafeSlow = function (size) {
	  return allocUnsafe(null, size)
	}
	
	function fromString (that, string, encoding) {
	  if (typeof encoding !== 'string' || encoding === '') {
	    encoding = 'utf8'
	  }
	
	  if (!Buffer.isEncoding(encoding)) {
	    throw new TypeError('"encoding" must be a valid string encoding')
	  }
	
	  var length = byteLength(string, encoding) | 0
	  that = createBuffer(that, length)
	
	  var actual = that.write(string, encoding)
	
	  if (actual !== length) {
	    // Writing a hex string, for example, that contains invalid characters will
	    // cause everything after the first invalid character to be ignored. (e.g.
	    // 'abxxcd' will be treated as 'ab')
	    that = that.slice(0, actual)
	  }
	
	  return that
	}
	
	function fromArrayLike (that, array) {
	  var length = array.length < 0 ? 0 : checked(array.length) | 0
	  that = createBuffer(that, length)
	  for (var i = 0; i < length; i += 1) {
	    that[i] = array[i] & 255
	  }
	  return that
	}
	
	function fromArrayBuffer (that, array, byteOffset, length) {
	  array.byteLength // this throws if `array` is not a valid ArrayBuffer
	
	  if (byteOffset < 0 || array.byteLength < byteOffset) {
	    throw new RangeError('\'offset\' is out of bounds')
	  }
	
	  if (array.byteLength < byteOffset + (length || 0)) {
	    throw new RangeError('\'length\' is out of bounds')
	  }
	
	  if (byteOffset === undefined && length === undefined) {
	    array = new Uint8Array(array)
	  } else if (length === undefined) {
	    array = new Uint8Array(array, byteOffset)
	  } else {
	    array = new Uint8Array(array, byteOffset, length)
	  }
	
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    // Return an augmented `Uint8Array` instance, for best performance
	    that = array
	    that.__proto__ = Buffer.prototype
	  } else {
	    // Fallback: Return an object instance of the Buffer class
	    that = fromArrayLike(that, array)
	  }
	  return that
	}
	
	function fromObject (that, obj) {
	  if (Buffer.isBuffer(obj)) {
	    var len = checked(obj.length) | 0
	    that = createBuffer(that, len)
	
	    if (that.length === 0) {
	      return that
	    }
	
	    obj.copy(that, 0, 0, len)
	    return that
	  }
	
	  if (obj) {
	    if ((typeof ArrayBuffer !== 'undefined' &&
	        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
	      if (typeof obj.length !== 'number' || isnan(obj.length)) {
	        return createBuffer(that, 0)
	      }
	      return fromArrayLike(that, obj)
	    }
	
	    if (obj.type === 'Buffer' && isArray(obj.data)) {
	      return fromArrayLike(that, obj.data)
	    }
	  }
	
	  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
	}
	
	function checked (length) {
	  // Note: cannot use `length < kMaxLength()` here because that fails when
	  // length is NaN (which is otherwise coerced to zero.)
	  if (length >= kMaxLength()) {
	    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
	                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
	  }
	  return length | 0
	}
	
	function SlowBuffer (length) {
	  if (+length != length) { // eslint-disable-line eqeqeq
	    length = 0
	  }
	  return Buffer.alloc(+length)
	}
	
	Buffer.isBuffer = function isBuffer (b) {
	  return !!(b != null && b._isBuffer)
	}
	
	Buffer.compare = function compare (a, b) {
	  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
	    throw new TypeError('Arguments must be Buffers')
	  }
	
	  if (a === b) return 0
	
	  var x = a.length
	  var y = b.length
	
	  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
	    if (a[i] !== b[i]) {
	      x = a[i]
	      y = b[i]
	      break
	    }
	  }
	
	  if (x < y) return -1
	  if (y < x) return 1
	  return 0
	}
	
	Buffer.isEncoding = function isEncoding (encoding) {
	  switch (String(encoding).toLowerCase()) {
	    case 'hex':
	    case 'utf8':
	    case 'utf-8':
	    case 'ascii':
	    case 'latin1':
	    case 'binary':
	    case 'base64':
	    case 'ucs2':
	    case 'ucs-2':
	    case 'utf16le':
	    case 'utf-16le':
	      return true
	    default:
	      return false
	  }
	}
	
	Buffer.concat = function concat (list, length) {
	  if (!isArray(list)) {
	    throw new TypeError('"list" argument must be an Array of Buffers')
	  }
	
	  if (list.length === 0) {
	    return Buffer.alloc(0)
	  }
	
	  var i
	  if (length === undefined) {
	    length = 0
	    for (i = 0; i < list.length; ++i) {
	      length += list[i].length
	    }
	  }
	
	  var buffer = Buffer.allocUnsafe(length)
	  var pos = 0
	  for (i = 0; i < list.length; ++i) {
	    var buf = list[i]
	    if (!Buffer.isBuffer(buf)) {
	      throw new TypeError('"list" argument must be an Array of Buffers')
	    }
	    buf.copy(buffer, pos)
	    pos += buf.length
	  }
	  return buffer
	}
	
	function byteLength (string, encoding) {
	  if (Buffer.isBuffer(string)) {
	    return string.length
	  }
	  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
	      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
	    return string.byteLength
	  }
	  if (typeof string !== 'string') {
	    string = '' + string
	  }
	
	  var len = string.length
	  if (len === 0) return 0
	
	  // Use a for loop to avoid recursion
	  var loweredCase = false
	  for (;;) {
	    switch (encoding) {
	      case 'ascii':
	      case 'latin1':
	      case 'binary':
	        return len
	      case 'utf8':
	      case 'utf-8':
	      case undefined:
	        return utf8ToBytes(string).length
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return len * 2
	      case 'hex':
	        return len >>> 1
	      case 'base64':
	        return base64ToBytes(string).length
	      default:
	        if (loweredCase) return utf8ToBytes(string).length // assume utf8
	        encoding = ('' + encoding).toLowerCase()
	        loweredCase = true
	    }
	  }
	}
	Buffer.byteLength = byteLength
	
	function slowToString (encoding, start, end) {
	  var loweredCase = false
	
	  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
	  // property of a typed array.
	
	  // This behaves neither like String nor Uint8Array in that we set start/end
	  // to their upper/lower bounds if the value passed is out of range.
	  // undefined is handled specially as per ECMA-262 6th Edition,
	  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
	  if (start === undefined || start < 0) {
	    start = 0
	  }
	  // Return early if start > this.length. Done here to prevent potential uint32
	  // coercion fail below.
	  if (start > this.length) {
	    return ''
	  }
	
	  if (end === undefined || end > this.length) {
	    end = this.length
	  }
	
	  if (end <= 0) {
	    return ''
	  }
	
	  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
	  end >>>= 0
	  start >>>= 0
	
	  if (end <= start) {
	    return ''
	  }
	
	  if (!encoding) encoding = 'utf8'
	
	  while (true) {
	    switch (encoding) {
	      case 'hex':
	        return hexSlice(this, start, end)
	
	      case 'utf8':
	      case 'utf-8':
	        return utf8Slice(this, start, end)
	
	      case 'ascii':
	        return asciiSlice(this, start, end)
	
	      case 'latin1':
	      case 'binary':
	        return latin1Slice(this, start, end)
	
	      case 'base64':
	        return base64Slice(this, start, end)
	
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return utf16leSlice(this, start, end)
	
	      default:
	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
	        encoding = (encoding + '').toLowerCase()
	        loweredCase = true
	    }
	  }
	}
	
	// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
	// Buffer instances.
	Buffer.prototype._isBuffer = true
	
	function swap (b, n, m) {
	  var i = b[n]
	  b[n] = b[m]
	  b[m] = i
	}
	
	Buffer.prototype.swap16 = function swap16 () {
	  var len = this.length
	  if (len % 2 !== 0) {
	    throw new RangeError('Buffer size must be a multiple of 16-bits')
	  }
	  for (var i = 0; i < len; i += 2) {
	    swap(this, i, i + 1)
	  }
	  return this
	}
	
	Buffer.prototype.swap32 = function swap32 () {
	  var len = this.length
	  if (len % 4 !== 0) {
	    throw new RangeError('Buffer size must be a multiple of 32-bits')
	  }
	  for (var i = 0; i < len; i += 4) {
	    swap(this, i, i + 3)
	    swap(this, i + 1, i + 2)
	  }
	  return this
	}
	
	Buffer.prototype.swap64 = function swap64 () {
	  var len = this.length
	  if (len % 8 !== 0) {
	    throw new RangeError('Buffer size must be a multiple of 64-bits')
	  }
	  for (var i = 0; i < len; i += 8) {
	    swap(this, i, i + 7)
	    swap(this, i + 1, i + 6)
	    swap(this, i + 2, i + 5)
	    swap(this, i + 3, i + 4)
	  }
	  return this
	}
	
	Buffer.prototype.toString = function toString () {
	  var length = this.length | 0
	  if (length === 0) return ''
	  if (arguments.length === 0) return utf8Slice(this, 0, length)
	  return slowToString.apply(this, arguments)
	}
	
	Buffer.prototype.equals = function equals (b) {
	  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
	  if (this === b) return true
	  return Buffer.compare(this, b) === 0
	}
	
	Buffer.prototype.inspect = function inspect () {
	  var str = ''
	  var max = exports.INSPECT_MAX_BYTES
	  if (this.length > 0) {
	    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
	    if (this.length > max) str += ' ... '
	  }
	  return '<Buffer ' + str + '>'
	}
	
	Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
	  if (!Buffer.isBuffer(target)) {
	    throw new TypeError('Argument must be a Buffer')
	  }
	
	  if (start === undefined) {
	    start = 0
	  }
	  if (end === undefined) {
	    end = target ? target.length : 0
	  }
	  if (thisStart === undefined) {
	    thisStart = 0
	  }
	  if (thisEnd === undefined) {
	    thisEnd = this.length
	  }
	
	  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
	    throw new RangeError('out of range index')
	  }
	
	  if (thisStart >= thisEnd && start >= end) {
	    return 0
	  }
	  if (thisStart >= thisEnd) {
	    return -1
	  }
	  if (start >= end) {
	    return 1
	  }
	
	  start >>>= 0
	  end >>>= 0
	  thisStart >>>= 0
	  thisEnd >>>= 0
	
	  if (this === target) return 0
	
	  var x = thisEnd - thisStart
	  var y = end - start
	  var len = Math.min(x, y)
	
	  var thisCopy = this.slice(thisStart, thisEnd)
	  var targetCopy = target.slice(start, end)
	
	  for (var i = 0; i < len; ++i) {
	    if (thisCopy[i] !== targetCopy[i]) {
	      x = thisCopy[i]
	      y = targetCopy[i]
	      break
	    }
	  }
	
	  if (x < y) return -1
	  if (y < x) return 1
	  return 0
	}
	
	// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
	// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
	//
	// Arguments:
	// - buffer - a Buffer to search
	// - val - a string, Buffer, or number
	// - byteOffset - an index into `buffer`; will be clamped to an int32
	// - encoding - an optional encoding, relevant is val is a string
	// - dir - true for indexOf, false for lastIndexOf
	function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
	  // Empty buffer means no match
	  if (buffer.length === 0) return -1
	
	  // Normalize byteOffset
	  if (typeof byteOffset === 'string') {
	    encoding = byteOffset
	    byteOffset = 0
	  } else if (byteOffset > 0x7fffffff) {
	    byteOffset = 0x7fffffff
	  } else if (byteOffset < -0x80000000) {
	    byteOffset = -0x80000000
	  }
	  byteOffset = +byteOffset  // Coerce to Number.
	  if (isNaN(byteOffset)) {
	    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
	    byteOffset = dir ? 0 : (buffer.length - 1)
	  }
	
	  // Normalize byteOffset: negative offsets start from the end of the buffer
	  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
	  if (byteOffset >= buffer.length) {
	    if (dir) return -1
	    else byteOffset = buffer.length - 1
	  } else if (byteOffset < 0) {
	    if (dir) byteOffset = 0
	    else return -1
	  }
	
	  // Normalize val
	  if (typeof val === 'string') {
	    val = Buffer.from(val, encoding)
	  }
	
	  // Finally, search either indexOf (if dir is true) or lastIndexOf
	  if (Buffer.isBuffer(val)) {
	    // Special case: looking for empty string/buffer always fails
	    if (val.length === 0) {
	      return -1
	    }
	    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
	  } else if (typeof val === 'number') {
	    val = val & 0xFF // Search for a byte value [0-255]
	    if (Buffer.TYPED_ARRAY_SUPPORT &&
	        typeof Uint8Array.prototype.indexOf === 'function') {
	      if (dir) {
	        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
	      } else {
	        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
	      }
	    }
	    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
	  }
	
	  throw new TypeError('val must be string, number or Buffer')
	}
	
	function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
	  var indexSize = 1
	  var arrLength = arr.length
	  var valLength = val.length
	
	  if (encoding !== undefined) {
	    encoding = String(encoding).toLowerCase()
	    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
	        encoding === 'utf16le' || encoding === 'utf-16le') {
	      if (arr.length < 2 || val.length < 2) {
	        return -1
	      }
	      indexSize = 2
	      arrLength /= 2
	      valLength /= 2
	      byteOffset /= 2
	    }
	  }
	
	  function read (buf, i) {
	    if (indexSize === 1) {
	      return buf[i]
	    } else {
	      return buf.readUInt16BE(i * indexSize)
	    }
	  }
	
	  var i
	  if (dir) {
	    var foundIndex = -1
	    for (i = byteOffset; i < arrLength; i++) {
	      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
	        if (foundIndex === -1) foundIndex = i
	        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
	      } else {
	        if (foundIndex !== -1) i -= i - foundIndex
	        foundIndex = -1
	      }
	    }
	  } else {
	    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
	    for (i = byteOffset; i >= 0; i--) {
	      var found = true
	      for (var j = 0; j < valLength; j++) {
	        if (read(arr, i + j) !== read(val, j)) {
	          found = false
	          break
	        }
	      }
	      if (found) return i
	    }
	  }
	
	  return -1
	}
	
	Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
	  return this.indexOf(val, byteOffset, encoding) !== -1
	}
	
	Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
	  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
	}
	
	Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
	  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
	}
	
	function hexWrite (buf, string, offset, length) {
	  offset = Number(offset) || 0
	  var remaining = buf.length - offset
	  if (!length) {
	    length = remaining
	  } else {
	    length = Number(length)
	    if (length > remaining) {
	      length = remaining
	    }
	  }
	
	  // must be an even number of digits
	  var strLen = string.length
	  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
	
	  if (length > strLen / 2) {
	    length = strLen / 2
	  }
	  for (var i = 0; i < length; ++i) {
	    var parsed = parseInt(string.substr(i * 2, 2), 16)
	    if (isNaN(parsed)) return i
	    buf[offset + i] = parsed
	  }
	  return i
	}
	
	function utf8Write (buf, string, offset, length) {
	  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
	}
	
	function asciiWrite (buf, string, offset, length) {
	  return blitBuffer(asciiToBytes(string), buf, offset, length)
	}
	
	function latin1Write (buf, string, offset, length) {
	  return asciiWrite(buf, string, offset, length)
	}
	
	function base64Write (buf, string, offset, length) {
	  return blitBuffer(base64ToBytes(string), buf, offset, length)
	}
	
	function ucs2Write (buf, string, offset, length) {
	  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
	}
	
	Buffer.prototype.write = function write (string, offset, length, encoding) {
	  // Buffer#write(string)
	  if (offset === undefined) {
	    encoding = 'utf8'
	    length = this.length
	    offset = 0
	  // Buffer#write(string, encoding)
	  } else if (length === undefined && typeof offset === 'string') {
	    encoding = offset
	    length = this.length
	    offset = 0
	  // Buffer#write(string, offset[, length][, encoding])
	  } else if (isFinite(offset)) {
	    offset = offset | 0
	    if (isFinite(length)) {
	      length = length | 0
	      if (encoding === undefined) encoding = 'utf8'
	    } else {
	      encoding = length
	      length = undefined
	    }
	  // legacy write(string, encoding, offset, length) - remove in v0.13
	  } else {
	    throw new Error(
	      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
	    )
	  }
	
	  var remaining = this.length - offset
	  if (length === undefined || length > remaining) length = remaining
	
	  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
	    throw new RangeError('Attempt to write outside buffer bounds')
	  }
	
	  if (!encoding) encoding = 'utf8'
	
	  var loweredCase = false
	  for (;;) {
	    switch (encoding) {
	      case 'hex':
	        return hexWrite(this, string, offset, length)
	
	      case 'utf8':
	      case 'utf-8':
	        return utf8Write(this, string, offset, length)
	
	      case 'ascii':
	        return asciiWrite(this, string, offset, length)
	
	      case 'latin1':
	      case 'binary':
	        return latin1Write(this, string, offset, length)
	
	      case 'base64':
	        // Warning: maxLength not taken into account in base64Write
	        return base64Write(this, string, offset, length)
	
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return ucs2Write(this, string, offset, length)
	
	      default:
	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
	        encoding = ('' + encoding).toLowerCase()
	        loweredCase = true
	    }
	  }
	}
	
	Buffer.prototype.toJSON = function toJSON () {
	  return {
	    type: 'Buffer',
	    data: Array.prototype.slice.call(this._arr || this, 0)
	  }
	}
	
	function base64Slice (buf, start, end) {
	  if (start === 0 && end === buf.length) {
	    return base64.fromByteArray(buf)
	  } else {
	    return base64.fromByteArray(buf.slice(start, end))
	  }
	}
	
	function utf8Slice (buf, start, end) {
	  end = Math.min(buf.length, end)
	  var res = []
	
	  var i = start
	  while (i < end) {
	    var firstByte = buf[i]
	    var codePoint = null
	    var bytesPerSequence = (firstByte > 0xEF) ? 4
	      : (firstByte > 0xDF) ? 3
	      : (firstByte > 0xBF) ? 2
	      : 1
	
	    if (i + bytesPerSequence <= end) {
	      var secondByte, thirdByte, fourthByte, tempCodePoint
	
	      switch (bytesPerSequence) {
	        case 1:
	          if (firstByte < 0x80) {
	            codePoint = firstByte
	          }
	          break
	        case 2:
	          secondByte = buf[i + 1]
	          if ((secondByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
	            if (tempCodePoint > 0x7F) {
	              codePoint = tempCodePoint
	            }
	          }
	          break
	        case 3:
	          secondByte = buf[i + 1]
	          thirdByte = buf[i + 2]
	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
	            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
	              codePoint = tempCodePoint
	            }
	          }
	          break
	        case 4:
	          secondByte = buf[i + 1]
	          thirdByte = buf[i + 2]
	          fourthByte = buf[i + 3]
	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
	            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
	              codePoint = tempCodePoint
	            }
	          }
	      }
	    }
	
	    if (codePoint === null) {
	      // we did not generate a valid codePoint so insert a
	      // replacement char (U+FFFD) and advance only 1 byte
	      codePoint = 0xFFFD
	      bytesPerSequence = 1
	    } else if (codePoint > 0xFFFF) {
	      // encode to utf16 (surrogate pair dance)
	      codePoint -= 0x10000
	      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
	      codePoint = 0xDC00 | codePoint & 0x3FF
	    }
	
	    res.push(codePoint)
	    i += bytesPerSequence
	  }
	
	  return decodeCodePointsArray(res)
	}
	
	// Based on http://stackoverflow.com/a/22747272/680742, the browser with
	// the lowest limit is Chrome, with 0x10000 args.
	// We go 1 magnitude less, for safety
	var MAX_ARGUMENTS_LENGTH = 0x1000
	
	function decodeCodePointsArray (codePoints) {
	  var len = codePoints.length
	  if (len <= MAX_ARGUMENTS_LENGTH) {
	    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
	  }
	
	  // Decode in chunks to avoid "call stack size exceeded".
	  var res = ''
	  var i = 0
	  while (i < len) {
	    res += String.fromCharCode.apply(
	      String,
	      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
	    )
	  }
	  return res
	}
	
	function asciiSlice (buf, start, end) {
	  var ret = ''
	  end = Math.min(buf.length, end)
	
	  for (var i = start; i < end; ++i) {
	    ret += String.fromCharCode(buf[i] & 0x7F)
	  }
	  return ret
	}
	
	function latin1Slice (buf, start, end) {
	  var ret = ''
	  end = Math.min(buf.length, end)
	
	  for (var i = start; i < end; ++i) {
	    ret += String.fromCharCode(buf[i])
	  }
	  return ret
	}
	
	function hexSlice (buf, start, end) {
	  var len = buf.length
	
	  if (!start || start < 0) start = 0
	  if (!end || end < 0 || end > len) end = len
	
	  var out = ''
	  for (var i = start; i < end; ++i) {
	    out += toHex(buf[i])
	  }
	  return out
	}
	
	function utf16leSlice (buf, start, end) {
	  var bytes = buf.slice(start, end)
	  var res = ''
	  for (var i = 0; i < bytes.length; i += 2) {
	    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
	  }
	  return res
	}
	
	Buffer.prototype.slice = function slice (start, end) {
	  var len = this.length
	  start = ~~start
	  end = end === undefined ? len : ~~end
	
	  if (start < 0) {
	    start += len
	    if (start < 0) start = 0
	  } else if (start > len) {
	    start = len
	  }
	
	  if (end < 0) {
	    end += len
	    if (end < 0) end = 0
	  } else if (end > len) {
	    end = len
	  }
	
	  if (end < start) end = start
	
	  var newBuf
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    newBuf = this.subarray(start, end)
	    newBuf.__proto__ = Buffer.prototype
	  } else {
	    var sliceLen = end - start
	    newBuf = new Buffer(sliceLen, undefined)
	    for (var i = 0; i < sliceLen; ++i) {
	      newBuf[i] = this[i + start]
	    }
	  }
	
	  return newBuf
	}
	
	/*
	 * Need to make sure that buffer isn't trying to write out of bounds.
	 */
	function checkOffset (offset, ext, length) {
	  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
	  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
	}
	
	Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)
	
	  var val = this[offset]
	  var mul = 1
	  var i = 0
	  while (++i < byteLength && (mul *= 0x100)) {
	    val += this[offset + i] * mul
	  }
	
	  return val
	}
	
	Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) {
	    checkOffset(offset, byteLength, this.length)
	  }
	
	  var val = this[offset + --byteLength]
	  var mul = 1
	  while (byteLength > 0 && (mul *= 0x100)) {
	    val += this[offset + --byteLength] * mul
	  }
	
	  return val
	}
	
	Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 1, this.length)
	  return this[offset]
	}
	
	Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  return this[offset] | (this[offset + 1] << 8)
	}
	
	Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  return (this[offset] << 8) | this[offset + 1]
	}
	
	Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return ((this[offset]) |
	      (this[offset + 1] << 8) |
	      (this[offset + 2] << 16)) +
	      (this[offset + 3] * 0x1000000)
	}
	
	Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return (this[offset] * 0x1000000) +
	    ((this[offset + 1] << 16) |
	    (this[offset + 2] << 8) |
	    this[offset + 3])
	}
	
	Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)
	
	  var val = this[offset]
	  var mul = 1
	  var i = 0
	  while (++i < byteLength && (mul *= 0x100)) {
	    val += this[offset + i] * mul
	  }
	  mul *= 0x80
	
	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
	
	  return val
	}
	
	Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)
	
	  var i = byteLength
	  var mul = 1
	  var val = this[offset + --i]
	  while (i > 0 && (mul *= 0x100)) {
	    val += this[offset + --i] * mul
	  }
	  mul *= 0x80
	
	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
	
	  return val
	}
	
	Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 1, this.length)
	  if (!(this[offset] & 0x80)) return (this[offset])
	  return ((0xff - this[offset] + 1) * -1)
	}
	
	Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  var val = this[offset] | (this[offset + 1] << 8)
	  return (val & 0x8000) ? val | 0xFFFF0000 : val
	}
	
	Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  var val = this[offset + 1] | (this[offset] << 8)
	  return (val & 0x8000) ? val | 0xFFFF0000 : val
	}
	
	Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return (this[offset]) |
	    (this[offset + 1] << 8) |
	    (this[offset + 2] << 16) |
	    (this[offset + 3] << 24)
	}
	
	Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return (this[offset] << 24) |
	    (this[offset + 1] << 16) |
	    (this[offset + 2] << 8) |
	    (this[offset + 3])
	}
	
	Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	  return ieee754.read(this, offset, true, 23, 4)
	}
	
	Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	  return ieee754.read(this, offset, false, 23, 4)
	}
	
	Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 8, this.length)
	  return ieee754.read(this, offset, true, 52, 8)
	}
	
	Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 8, this.length)
	  return ieee754.read(this, offset, false, 52, 8)
	}
	
	function checkInt (buf, value, offset, ext, max, min) {
	  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
	  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
	  if (offset + ext > buf.length) throw new RangeError('Index out of range')
	}
	
	Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) {
	    var maxBytes = Math.pow(2, 8 * byteLength) - 1
	    checkInt(this, value, offset, byteLength, maxBytes, 0)
	  }
	
	  var mul = 1
	  var i = 0
	  this[offset] = value & 0xFF
	  while (++i < byteLength && (mul *= 0x100)) {
	    this[offset + i] = (value / mul) & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) {
	    var maxBytes = Math.pow(2, 8 * byteLength) - 1
	    checkInt(this, value, offset, byteLength, maxBytes, 0)
	  }
	
	  var i = byteLength - 1
	  var mul = 1
	  this[offset + i] = value & 0xFF
	  while (--i >= 0 && (mul *= 0x100)) {
	    this[offset + i] = (value / mul) & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
	  this[offset] = (value & 0xff)
	  return offset + 1
	}
	
	function objectWriteUInt16 (buf, value, offset, littleEndian) {
	  if (value < 0) value = 0xffff + value + 1
	  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
	    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
	      (littleEndian ? i : 1 - i) * 8
	  }
	}
	
	Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	  } else {
	    objectWriteUInt16(this, value, offset, true)
	  }
	  return offset + 2
	}
	
	Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 8)
	    this[offset + 1] = (value & 0xff)
	  } else {
	    objectWriteUInt16(this, value, offset, false)
	  }
	  return offset + 2
	}
	
	function objectWriteUInt32 (buf, value, offset, littleEndian) {
	  if (value < 0) value = 0xffffffff + value + 1
	  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
	    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
	  }
	}
	
	Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset + 3] = (value >>> 24)
	    this[offset + 2] = (value >>> 16)
	    this[offset + 1] = (value >>> 8)
	    this[offset] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, true)
	  }
	  return offset + 4
	}
	
	Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 24)
	    this[offset + 1] = (value >>> 16)
	    this[offset + 2] = (value >>> 8)
	    this[offset + 3] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, false)
	  }
	  return offset + 4
	}
	
	Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) {
	    var limit = Math.pow(2, 8 * byteLength - 1)
	
	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
	  }
	
	  var i = 0
	  var mul = 1
	  var sub = 0
	  this[offset] = value & 0xFF
	  while (++i < byteLength && (mul *= 0x100)) {
	    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
	      sub = 1
	    }
	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) {
	    var limit = Math.pow(2, 8 * byteLength - 1)
	
	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
	  }
	
	  var i = byteLength - 1
	  var mul = 1
	  var sub = 0
	  this[offset + i] = value & 0xFF
	  while (--i >= 0 && (mul *= 0x100)) {
	    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
	      sub = 1
	    }
	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
	  if (value < 0) value = 0xff + value + 1
	  this[offset] = (value & 0xff)
	  return offset + 1
	}
	
	Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	  } else {
	    objectWriteUInt16(this, value, offset, true)
	  }
	  return offset + 2
	}
	
	Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 8)
	    this[offset + 1] = (value & 0xff)
	  } else {
	    objectWriteUInt16(this, value, offset, false)
	  }
	  return offset + 2
	}
	
	Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	    this[offset + 2] = (value >>> 16)
	    this[offset + 3] = (value >>> 24)
	  } else {
	    objectWriteUInt32(this, value, offset, true)
	  }
	  return offset + 4
	}
	
	Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
	  if (value < 0) value = 0xffffffff + value + 1
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 24)
	    this[offset + 1] = (value >>> 16)
	    this[offset + 2] = (value >>> 8)
	    this[offset + 3] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, false)
	  }
	  return offset + 4
	}
	
	function checkIEEE754 (buf, value, offset, ext, max, min) {
	  if (offset + ext > buf.length) throw new RangeError('Index out of range')
	  if (offset < 0) throw new RangeError('Index out of range')
	}
	
	function writeFloat (buf, value, offset, littleEndian, noAssert) {
	  if (!noAssert) {
	    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
	  }
	  ieee754.write(buf, value, offset, littleEndian, 23, 4)
	  return offset + 4
	}
	
	Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
	  return writeFloat(this, value, offset, true, noAssert)
	}
	
	Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
	  return writeFloat(this, value, offset, false, noAssert)
	}
	
	function writeDouble (buf, value, offset, littleEndian, noAssert) {
	  if (!noAssert) {
	    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
	  }
	  ieee754.write(buf, value, offset, littleEndian, 52, 8)
	  return offset + 8
	}
	
	Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
	  return writeDouble(this, value, offset, true, noAssert)
	}
	
	Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
	  return writeDouble(this, value, offset, false, noAssert)
	}
	
	// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
	Buffer.prototype.copy = function copy (target, targetStart, start, end) {
	  if (!start) start = 0
	  if (!end && end !== 0) end = this.length
	  if (targetStart >= target.length) targetStart = target.length
	  if (!targetStart) targetStart = 0
	  if (end > 0 && end < start) end = start
	
	  // Copy 0 bytes; we're done
	  if (end === start) return 0
	  if (target.length === 0 || this.length === 0) return 0
	
	  // Fatal error conditions
	  if (targetStart < 0) {
	    throw new RangeError('targetStart out of bounds')
	  }
	  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
	  if (end < 0) throw new RangeError('sourceEnd out of bounds')
	
	  // Are we oob?
	  if (end > this.length) end = this.length
	  if (target.length - targetStart < end - start) {
	    end = target.length - targetStart + start
	  }
	
	  var len = end - start
	  var i
	
	  if (this === target && start < targetStart && targetStart < end) {
	    // descending copy from end
	    for (i = len - 1; i >= 0; --i) {
	      target[i + targetStart] = this[i + start]
	    }
	  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
	    // ascending copy from start
	    for (i = 0; i < len; ++i) {
	      target[i + targetStart] = this[i + start]
	    }
	  } else {
	    Uint8Array.prototype.set.call(
	      target,
	      this.subarray(start, start + len),
	      targetStart
	    )
	  }
	
	  return len
	}
	
	// Usage:
	//    buffer.fill(number[, offset[, end]])
	//    buffer.fill(buffer[, offset[, end]])
	//    buffer.fill(string[, offset[, end]][, encoding])
	Buffer.prototype.fill = function fill (val, start, end, encoding) {
	  // Handle string cases:
	  if (typeof val === 'string') {
	    if (typeof start === 'string') {
	      encoding = start
	      start = 0
	      end = this.length
	    } else if (typeof end === 'string') {
	      encoding = end
	      end = this.length
	    }
	    if (val.length === 1) {
	      var code = val.charCodeAt(0)
	      if (code < 256) {
	        val = code
	      }
	    }
	    if (encoding !== undefined && typeof encoding !== 'string') {
	      throw new TypeError('encoding must be a string')
	    }
	    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
	      throw new TypeError('Unknown encoding: ' + encoding)
	    }
	  } else if (typeof val === 'number') {
	    val = val & 255
	  }
	
	  // Invalid ranges are not set to a default, so can range check early.
	  if (start < 0 || this.length < start || this.length < end) {
	    throw new RangeError('Out of range index')
	  }
	
	  if (end <= start) {
	    return this
	  }
	
	  start = start >>> 0
	  end = end === undefined ? this.length : end >>> 0
	
	  if (!val) val = 0
	
	  var i
	  if (typeof val === 'number') {
	    for (i = start; i < end; ++i) {
	      this[i] = val
	    }
	  } else {
	    var bytes = Buffer.isBuffer(val)
	      ? val
	      : utf8ToBytes(new Buffer(val, encoding).toString())
	    var len = bytes.length
	    for (i = 0; i < end - start; ++i) {
	      this[i + start] = bytes[i % len]
	    }
	  }
	
	  return this
	}
	
	// HELPER FUNCTIONS
	// ================
	
	var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
	
	function base64clean (str) {
	  // Node strips out invalid characters like \n and \t from the string, base64-js does not
	  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
	  // Node converts strings with length < 2 to ''
	  if (str.length < 2) return ''
	  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
	  while (str.length % 4 !== 0) {
	    str = str + '='
	  }
	  return str
	}
	
	function stringtrim (str) {
	  if (str.trim) return str.trim()
	  return str.replace(/^\s+|\s+$/g, '')
	}
	
	function toHex (n) {
	  if (n < 16) return '0' + n.toString(16)
	  return n.toString(16)
	}
	
	function utf8ToBytes (string, units) {
	  units = units || Infinity
	  var codePoint
	  var length = string.length
	  var leadSurrogate = null
	  var bytes = []
	
	  for (var i = 0; i < length; ++i) {
	    codePoint = string.charCodeAt(i)
	
	    // is surrogate component
	    if (codePoint > 0xD7FF && codePoint < 0xE000) {
	      // last char was a lead
	      if (!leadSurrogate) {
	        // no lead yet
	        if (codePoint > 0xDBFF) {
	          // unexpected trail
	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	          continue
	        } else if (i + 1 === length) {
	          // unpaired lead
	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	          continue
	        }
	
	        // valid lead
	        leadSurrogate = codePoint
	
	        continue
	      }
	
	      // 2 leads in a row
	      if (codePoint < 0xDC00) {
	        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	        leadSurrogate = codePoint
	        continue
	      }
	
	      // valid surrogate pair
	      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
	    } else if (leadSurrogate) {
	      // valid bmp char, but last char was a lead
	      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	    }
	
	    leadSurrogate = null
	
	    // encode utf8
	    if (codePoint < 0x80) {
	      if ((units -= 1) < 0) break
	      bytes.push(codePoint)
	    } else if (codePoint < 0x800) {
	      if ((units -= 2) < 0) break
	      bytes.push(
	        codePoint >> 0x6 | 0xC0,
	        codePoint & 0x3F | 0x80
	      )
	    } else if (codePoint < 0x10000) {
	      if ((units -= 3) < 0) break
	      bytes.push(
	        codePoint >> 0xC | 0xE0,
	        codePoint >> 0x6 & 0x3F | 0x80,
	        codePoint & 0x3F | 0x80
	      )
	    } else if (codePoint < 0x110000) {
	      if ((units -= 4) < 0) break
	      bytes.push(
	        codePoint >> 0x12 | 0xF0,
	        codePoint >> 0xC & 0x3F | 0x80,
	        codePoint >> 0x6 & 0x3F | 0x80,
	        codePoint & 0x3F | 0x80
	      )
	    } else {
	      throw new Error('Invalid code point')
	    }
	  }
	
	  return bytes
	}
	
	function asciiToBytes (str) {
	  var byteArray = []
	  for (var i = 0; i < str.length; ++i) {
	    // Node's code seems to be doing this and not & 0x7F..
	    byteArray.push(str.charCodeAt(i) & 0xFF)
	  }
	  return byteArray
	}
	
	function utf16leToBytes (str, units) {
	  var c, hi, lo
	  var byteArray = []
	  for (var i = 0; i < str.length; ++i) {
	    if ((units -= 2) < 0) break
	
	    c = str.charCodeAt(i)
	    hi = c >> 8
	    lo = c % 256
	    byteArray.push(lo)
	    byteArray.push(hi)
	  }
	
	  return byteArray
	}
	
	function base64ToBytes (str) {
	  return base64.toByteArray(base64clean(str))
	}
	
	function blitBuffer (src, dst, offset, length) {
	  for (var i = 0; i < length; ++i) {
	    if ((i + offset >= dst.length) || (i >= src.length)) break
	    dst[i + offset] = src[i]
	  }
	  return i
	}
	
	function isnan (val) {
	  return val !== val // eslint-disable-line no-self-compare
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

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

	exports.read = function (buffer, offset, isLE, mLen, nBytes) {
	  var e, m
	  var eLen = nBytes * 8 - mLen - 1
	  var eMax = (1 << eLen) - 1
	  var eBias = eMax >> 1
	  var nBits = -7
	  var i = isLE ? (nBytes - 1) : 0
	  var d = isLE ? -1 : 1
	  var s = buffer[offset + i]
	
	  i += d
	
	  e = s & ((1 << (-nBits)) - 1)
	  s >>= (-nBits)
	  nBits += eLen
	  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
	
	  m = e & ((1 << (-nBits)) - 1)
	  e >>= (-nBits)
	  nBits += mLen
	  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
	
	  if (e === 0) {
	    e = 1 - eBias
	  } else if (e === eMax) {
	    return m ? NaN : ((s ? -1 : 1) * Infinity)
	  } else {
	    m = m + Math.pow(2, mLen)
	    e = e - eBias
	  }
	  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
	}
	
	exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
	  var e, m, c
	  var eLen = nBytes * 8 - mLen - 1
	  var eMax = (1 << eLen) - 1
	  var eBias = eMax >> 1
	  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
	  var i = isLE ? 0 : (nBytes - 1)
	  var d = isLE ? 1 : -1
	  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
	
	  value = Math.abs(value)
	
	  if (isNaN(value) || value === Infinity) {
	    m = isNaN(value) ? 1 : 0
	    e = eMax
	  } else {
	    e = Math.floor(Math.log(value) / Math.LN2)
	    if (value * (c = Math.pow(2, -e)) < 1) {
	      e--
	      c *= 2
	    }
	    if (e + eBias >= 1) {
	      value += rt / c
	    } else {
	      value += rt * Math.pow(2, 1 - eBias)
	    }
	    if (value * c >= 2) {
	      e++
	      c /= 2
	    }
	
	    if (e + eBias >= eMax) {
	      m = 0
	      e = eMax
	    } else if (e + eBias >= 1) {
	      m = (value * c - 1) * Math.pow(2, mLen)
	      e = e + eBias
	    } else {
	      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
	      e = 0
	    }
	  }
	
	  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
	
	  e = (e << mLen) | m
	  eLen += mLen
	  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
	
	  buffer[offset + i - d] |= s * 128
	}


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

	var toString = {}.toString;
	
	module.exports = Array.isArray || function (arr) {
	  return toString.call(arr) == '[object Array]';
	};


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

	/* WEBPACK VAR INJECTION */(function(global, Buffer) {(function() {
	  var g = ('undefined' === typeof window ? global : window) || {}
	  _crypto = (
	    g.crypto || g.msCrypto || __webpack_require__(16)
	  )
	  module.exports = function(size) {
	    // Modern Browsers
	    if(_crypto.getRandomValues) {
	      var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array
	      /* This will not work in older browsers.
	       * See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
	       */
	    
	      _crypto.getRandomValues(bytes);
	      return bytes;
	    }
	    else if (_crypto.randomBytes) {
	      return _crypto.randomBytes(size)
	    }
	    else
	      throw new Error(
	        'secure random number generation not supported by this browser\n'+
	        'use chrome, FireFox or Internet Explorer 11'
	      )
	  }
	}())
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(12).Buffer))

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

	/* (ignored) */

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var createHash = __webpack_require__(18)
	
	var md5 = toConstructor(__webpack_require__(27))
	var rmd160 = toConstructor(__webpack_require__(29))
	
	function toConstructor (fn) {
	  return function () {
	    var buffers = []
	    var m= {
	      update: function (data, enc) {
	        if(!Buffer.isBuffer(data)) data = new Buffer(data, enc)
	        buffers.push(data)
	        return this
	      },
	      digest: function (enc) {
	        var buf = Buffer.concat(buffers)
	        var r = fn(buf)
	        buffers = null
	        return enc ? r.toString(enc) : r
	      }
	    }
	    return m
	  }
	}
	
	module.exports = function (alg) {
	  if('md5' === alg) return new md5()
	  if('rmd160' === alg) return new rmd160()
	  return createHash(alg)
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	var exports = module.exports = function (alg) {
	  var Alg = exports[alg]
	  if(!Alg) throw new Error(alg + ' is not supported (we accept pull requests)')
	  return new Alg()
	}
	
	var Buffer = __webpack_require__(12).Buffer
	var Hash   = __webpack_require__(19)(Buffer)
	
	exports.sha1 = __webpack_require__(20)(Buffer, Hash)
	exports.sha256 = __webpack_require__(25)(Buffer, Hash)
	exports.sha512 = __webpack_require__(26)(Buffer, Hash)


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

	module.exports = function (Buffer) {
	
	  //prototype class for hash functions
	  function Hash (blockSize, finalSize) {
	    this._block = new Buffer(blockSize) //new Uint32Array(blockSize/4)
	    this._finalSize = finalSize
	    this._blockSize = blockSize
	    this._len = 0
	    this._s = 0
	  }
	
	  Hash.prototype.init = function () {
	    this._s = 0
	    this._len = 0
	  }
	
	  Hash.prototype.update = function (data, enc) {
	    if ("string" === typeof data) {
	      enc = enc || "utf8"
	      data = new Buffer(data, enc)
	    }
	
	    var l = this._len += data.length
	    var s = this._s = (this._s || 0)
	    var f = 0
	    var buffer = this._block
	
	    while (s < l) {
	      var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize))
	      var ch = (t - f)
	
	      for (var i = 0; i < ch; i++) {
	        buffer[(s % this._blockSize) + i] = data[i + f]
	      }
	
	      s += ch
	      f += ch
	
	      if ((s % this._blockSize) === 0) {
	        this._update(buffer)
	      }
	    }
	    this._s = s
	
	    return this
	  }
	
	  Hash.prototype.digest = function (enc) {
	    // Suppose the length of the message M, in bits, is l
	    var l = this._len * 8
	
	    // Append the bit 1 to the end of the message
	    this._block[this._len % this._blockSize] = 0x80
	
	    // and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize
	    this._block.fill(0, this._len % this._blockSize + 1)
	
	    if (l % (this._blockSize * 8) >= this._finalSize * 8) {
	      this._update(this._block)
	      this._block.fill(0)
	    }
	
	    // to this append the block which is equal to the number l written in binary
	    // TODO: handle case where l is > Math.pow(2, 29)
	    this._block.writeInt32BE(l, this._blockSize - 4)
	
	    var hash = this._update(this._block) || this._hash()
	
	    return enc ? hash.toString(enc) : hash
	  }
	
	  Hash.prototype._update = function () {
	    throw new Error('_update must be implemented by subclass')
	  }
	
	  return Hash
	}


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

	/*
	 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
	 * in FIPS PUB 180-1
	 * Version 2.1a Copyright Paul Johnston 2000 - 2002.
	 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
	 * Distributed under the BSD License
	 * See http://pajhome.org.uk/crypt/md5 for details.
	 */
	
	var inherits = __webpack_require__(21).inherits
	
	module.exports = function (Buffer, Hash) {
	
	  var A = 0|0
	  var B = 4|0
	  var C = 8|0
	  var D = 12|0
	  var E = 16|0
	
	  var W = new (typeof Int32Array === 'undefined' ? Array : Int32Array)(80)
	
	  var POOL = []
	
	  function Sha1 () {
	    if(POOL.length)
	      return POOL.pop().init()
	
	    if(!(this instanceof Sha1)) return new Sha1()
	    this._w = W
	    Hash.call(this, 16*4, 14*4)
	
	    this._h = null
	    this.init()
	  }
	
	  inherits(Sha1, Hash)
	
	  Sha1.prototype.init = function () {
	    this._a = 0x67452301
	    this._b = 0xefcdab89
	    this._c = 0x98badcfe
	    this._d = 0x10325476
	    this._e = 0xc3d2e1f0
	
	    Hash.prototype.init.call(this)
	    return this
	  }
	
	  Sha1.prototype._POOL = POOL
	  Sha1.prototype._update = function (X) {
	
	    var a, b, c, d, e, _a, _b, _c, _d, _e
	
	    a = _a = this._a
	    b = _b = this._b
	    c = _c = this._c
	    d = _d = this._d
	    e = _e = this._e
	
	    var w = this._w
	
	    for(var j = 0; j < 80; j++) {
	      var W = w[j] = j < 16 ? X.readInt32BE(j*4)
	        : rol(w[j - 3] ^ w[j -  8] ^ w[j - 14] ^ w[j - 16], 1)
	
	      var t = add(
	        add(rol(a, 5), sha1_ft(j, b, c, d)),
	        add(add(e, W), sha1_kt(j))
	      )
	
	      e = d
	      d = c
	      c = rol(b, 30)
	      b = a
	      a = t
	    }
	
	    this._a = add(a, _a)
	    this._b = add(b, _b)
	    this._c = add(c, _c)
	    this._d = add(d, _d)
	    this._e = add(e, _e)
	  }
	
	  Sha1.prototype._hash = function () {
	    if(POOL.length < 100) POOL.push(this)
	    var H = new Buffer(20)
	    //console.log(this._a|0, this._b|0, this._c|0, this._d|0, this._e|0)
	    H.writeInt32BE(this._a|0, A)
	    H.writeInt32BE(this._b|0, B)
	    H.writeInt32BE(this._c|0, C)
	    H.writeInt32BE(this._d|0, D)
	    H.writeInt32BE(this._e|0, E)
	    return H
	  }
	
	  /*
	   * Perform the appropriate triplet combination function for the current
	   * iteration
	   */
	  function sha1_ft(t, b, c, d) {
	    if(t < 20) return (b & c) | ((~b) & d);
	    if(t < 40) return b ^ c ^ d;
	    if(t < 60) return (b & c) | (b & d) | (c & d);
	    return b ^ c ^ d;
	  }
	
	  /*
	   * Determine the appropriate additive constant for the current iteration
	   */
	  function sha1_kt(t) {
	    return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
	           (t < 60) ? -1894007588 : -899497514;
	  }
	
	  /*
	   * Add integers, wrapping at 2^32. This uses 16-bit operations internally
	   * to work around bugs in some JS interpreters.
	   * //dominictarr: this is 10 years old, so maybe this can be dropped?)
	   *
	   */
	  function add(x, y) {
	    return (x + y ) | 0
	  //lets see how this goes on testling.
	  //  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
	  //  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
	  //  return (msw << 16) | (lsw & 0xFFFF);
	  }
	
	  /*
	   * Bitwise rotate a 32-bit number to the left.
	   */
	  function rol(num, cnt) {
	    return (num << cnt) | (num >>> (32 - cnt));
	  }
	
	  return Sha1
	}


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

	/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	var formatRegExp = /%[sdj%]/g;
	exports.format = function(f) {
	  if (!isString(f)) {
	    var objects = [];
	    for (var i = 0; i < arguments.length; i++) {
	      objects.push(inspect(arguments[i]));
	    }
	    return objects.join(' ');
	  }
	
	  var i = 1;
	  var args = arguments;
	  var len = args.length;
	  var str = String(f).replace(formatRegExp, function(x) {
	    if (x === '%%') return '%';
	    if (i >= len) return x;
	    switch (x) {
	      case '%s': return String(args[i++]);
	      case '%d': return Number(args[i++]);
	      case '%j':
	        try {
	          return JSON.stringify(args[i++]);
	        } catch (_) {
	          return '[Circular]';
	        }
	      default:
	        return x;
	    }
	  });
	  for (var x = args[i]; i < len; x = args[++i]) {
	    if (isNull(x) || !isObject(x)) {
	      str += ' ' + x;
	    } else {
	      str += ' ' + inspect(x);
	    }
	  }
	  return str;
	};
	
	
	// Mark that a method should not be used.
	// Returns a modified function which warns once by default.
	// If --no-deprecation is set, then it is a no-op.
	exports.deprecate = function(fn, msg) {
	  // Allow for deprecating things in the process of starting up.
	  if (isUndefined(global.process)) {
	    return function() {
	      return exports.deprecate(fn, msg).apply(this, arguments);
	    };
	  }
	
	  if (process.noDeprecation === true) {
	    return fn;
	  }
	
	  var warned = false;
	  function deprecated() {
	    if (!warned) {
	      if (process.throwDeprecation) {
	        throw new Error(msg);
	      } else if (process.traceDeprecation) {
	        console.trace(msg);
	      } else {
	        console.error(msg);
	      }
	      warned = true;
	    }
	    return fn.apply(this, arguments);
	  }
	
	  return deprecated;
	};
	
	
	var debugs = {};
	var debugEnviron;
	exports.debuglog = function(set) {
	  if (isUndefined(debugEnviron))
	    debugEnviron = process.env.NODE_DEBUG || '';
	  set = set.toUpperCase();
	  if (!debugs[set]) {
	    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
	      var pid = process.pid;
	      debugs[set] = function() {
	        var msg = exports.format.apply(exports, arguments);
	        console.error('%s %d: %s', set, pid, msg);
	      };
	    } else {
	      debugs[set] = function() {};
	    }
	  }
	  return debugs[set];
	};
	
	
	/**
	 * Echos the value of a value. Trys to print the value out
	 * in the best way possible given the different types.
	 *
	 * @param {Object} obj The object to print out.
	 * @param {Object} opts Optional options object that alters the output.
	 */
	/* legacy: obj, showHidden, depth, colors*/
	function inspect(obj, opts) {
	  // default options
	  var ctx = {
	    seen: [],
	    stylize: stylizeNoColor
	  };
	  // legacy...
	  if (arguments.length >= 3) ctx.depth = arguments[2];
	  if (arguments.length >= 4) ctx.colors = arguments[3];
	  if (isBoolean(opts)) {
	    // legacy...
	    ctx.showHidden = opts;
	  } else if (opts) {
	    // got an "options" object
	    exports._extend(ctx, opts);
	  }
	  // set default options
	  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
	  if (isUndefined(ctx.depth)) ctx.depth = 2;
	  if (isUndefined(ctx.colors)) ctx.colors = false;
	  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
	  if (ctx.colors) ctx.stylize = stylizeWithColor;
	  return formatValue(ctx, obj, ctx.depth);
	}
	exports.inspect = inspect;
	
	
	// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
	inspect.colors = {
	  'bold' : [1, 22],
	  'italic' : [3, 23],
	  'underline' : [4, 24],
	  'inverse' : [7, 27],
	  'white' : [37, 39],
	  'grey' : [90, 39],
	  'black' : [30, 39],
	  'blue' : [34, 39],
	  'cyan' : [36, 39],
	  'green' : [32, 39],
	  'magenta' : [35, 39],
	  'red' : [31, 39],
	  'yellow' : [33, 39]
	};
	
	// Don't use 'blue' not visible on cmd.exe
	inspect.styles = {
	  'special': 'cyan',
	  'number': 'yellow',
	  'boolean': 'yellow',
	  'undefined': 'grey',
	  'null': 'bold',
	  'string': 'green',
	  'date': 'magenta',
	  // "name": intentionally not styling
	  'regexp': 'red'
	};
	
	
	function stylizeWithColor(str, styleType) {
	  var style = inspect.styles[styleType];
	
	  if (style) {
	    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
	           '\u001b[' + inspect.colors[style][1] + 'm';
	  } else {
	    return str;
	  }
	}
	
	
	function stylizeNoColor(str, styleType) {
	  return str;
	}
	
	
	function arrayToHash(array) {
	  var hash = {};
	
	  array.forEach(function(val, idx) {
	    hash[val] = true;
	  });
	
	  return hash;
	}
	
	
	function formatValue(ctx, value, recurseTimes) {
	  // Provide a hook for user-specified inspect functions.
	  // Check that value is an object with an inspect function on it
	  if (ctx.customInspect &&
	      value &&
	      isFunction(value.inspect) &&
	      // Filter out the util module, it's inspect function is special
	      value.inspect !== exports.inspect &&
	      // Also filter out any prototype objects using the circular check.
	      !(value.constructor && value.constructor.prototype === value)) {
	    var ret = value.inspect(recurseTimes, ctx);
	    if (!isString(ret)) {
	      ret = formatValue(ctx, ret, recurseTimes);
	    }
	    return ret;
	  }
	
	  // Primitive types cannot have properties
	  var primitive = formatPrimitive(ctx, value);
	  if (primitive) {
	    return primitive;
	  }
	
	  // Look up the keys of the object.
	  var keys = Object.keys(value);
	  var visibleKeys = arrayToHash(keys);
	
	  if (ctx.showHidden) {
	    keys = Object.getOwnPropertyNames(value);
	  }
	
	  // IE doesn't make error fields non-enumerable
	  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
	  if (isError(value)
	      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
	    return formatError(value);
	  }
	
	  // Some type of object without properties can be shortcutted.
	  if (keys.length === 0) {
	    if (isFunction(value)) {
	      var name = value.name ? ': ' + value.name : '';
	      return ctx.stylize('[Function' + name + ']', 'special');
	    }
	    if (isRegExp(value)) {
	      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
	    }
	    if (isDate(value)) {
	      return ctx.stylize(Date.prototype.toString.call(value), 'date');
	    }
	    if (isError(value)) {
	      return formatError(value);
	    }
	  }
	
	  var base = '', array = false, braces = ['{', '}'];
	
	  // Make Array say that they are Array
	  if (isArray(value)) {
	    array = true;
	    braces = ['[', ']'];
	  }
	
	  // Make functions say that they are functions
	  if (isFunction(value)) {
	    var n = value.name ? ': ' + value.name : '';
	    base = ' [Function' + n + ']';
	  }
	
	  // Make RegExps say that they are RegExps
	  if (isRegExp(value)) {
	    base = ' ' + RegExp.prototype.toString.call(value);
	  }
	
	  // Make dates with properties first say the date
	  if (isDate(value)) {
	    base = ' ' + Date.prototype.toUTCString.call(value);
	  }
	
	  // Make error with message first say the error
	  if (isError(value)) {
	    base = ' ' + formatError(value);
	  }
	
	  if (keys.length === 0 && (!array || value.length == 0)) {
	    return braces[0] + base + braces[1];
	  }
	
	  if (recurseTimes < 0) {
	    if (isRegExp(value)) {
	      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
	    } else {
	      return ctx.stylize('[Object]', 'special');
	    }
	  }
	
	  ctx.seen.push(value);
	
	  var output;
	  if (array) {
	    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
	  } else {
	    output = keys.map(function(key) {
	      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
	    });
	  }
	
	  ctx.seen.pop();
	
	  return reduceToSingleString(output, base, braces);
	}
	
	
	function formatPrimitive(ctx, value) {
	  if (isUndefined(value))
	    return ctx.stylize('undefined', 'undefined');
	  if (isString(value)) {
	    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
	                                             .replace(/'/g, "\\'")
	                                             .replace(/\\"/g, '"') + '\'';
	    return ctx.stylize(simple, 'string');
	  }
	  if (isNumber(value))
	    return ctx.stylize('' + value, 'number');
	  if (isBoolean(value))
	    return ctx.stylize('' + value, 'boolean');
	  // For some reason typeof null is "object", so special case here.
	  if (isNull(value))
	    return ctx.stylize('null', 'null');
	}
	
	
	function formatError(value) {
	  return '[' + Error.prototype.toString.call(value) + ']';
	}
	
	
	function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
	  var output = [];
	  for (var i = 0, l = value.length; i < l; ++i) {
	    if (hasOwnProperty(value, String(i))) {
	      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
	          String(i), true));
	    } else {
	      output.push('');
	    }
	  }
	  keys.forEach(function(key) {
	    if (!key.match(/^\d+$/)) {
	      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
	          key, true));
	    }
	  });
	  return output;
	}
	
	
	function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
	  var name, str, desc;
	  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
	  if (desc.get) {
	    if (desc.set) {
	      str = ctx.stylize('[Getter/Setter]', 'special');
	    } else {
	      str = ctx.stylize('[Getter]', 'special');
	    }
	  } else {
	    if (desc.set) {
	      str = ctx.stylize('[Setter]', 'special');
	    }
	  }
	  if (!hasOwnProperty(visibleKeys, key)) {
	    name = '[' + key + ']';
	  }
	  if (!str) {
	    if (ctx.seen.indexOf(desc.value) < 0) {
	      if (isNull(recurseTimes)) {
	        str = formatValue(ctx, desc.value, null);
	      } else {
	        str = formatValue(ctx, desc.value, recurseTimes - 1);
	      }
	      if (str.indexOf('\n') > -1) {
	        if (array) {
	          str = str.split('\n').map(function(line) {
	            return '  ' + line;
	          }).join('\n').substr(2);
	        } else {
	          str = '\n' + str.split('\n').map(function(line) {
	            return '   ' + line;
	          }).join('\n');
	        }
	      }
	    } else {
	      str = ctx.stylize('[Circular]', 'special');
	    }
	  }
	  if (isUndefined(name)) {
	    if (array && key.match(/^\d+$/)) {
	      return str;
	    }
	    name = JSON.stringify('' + key);
	    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
	      name = name.substr(1, name.length - 2);
	      name = ctx.stylize(name, 'name');
	    } else {
	      name = name.replace(/'/g, "\\'")
	                 .replace(/\\"/g, '"')
	                 .replace(/(^"|"$)/g, "'");
	      name = ctx.stylize(name, 'string');
	    }
	  }
	
	  return name + ': ' + str;
	}
	
	
	function reduceToSingleString(output, base, braces) {
	  var numLinesEst = 0;
	  var length = output.reduce(function(prev, cur) {
	    numLinesEst++;
	    if (cur.indexOf('\n') >= 0) numLinesEst++;
	    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
	  }, 0);
	
	  if (length > 60) {
	    return braces[0] +
	           (base === '' ? '' : base + '\n ') +
	           ' ' +
	           output.join(',\n  ') +
	           ' ' +
	           braces[1];
	  }
	
	  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
	}
	
	
	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.
	function isArray(ar) {
	  return Array.isArray(ar);
	}
	exports.isArray = isArray;
	
	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	exports.isBoolean = isBoolean;
	
	function isNull(arg) {
	  return arg === null;
	}
	exports.isNull = isNull;
	
	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	exports.isNullOrUndefined = isNullOrUndefined;
	
	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	exports.isNumber = isNumber;
	
	function isString(arg) {
	  return typeof arg === 'string';
	}
	exports.isString = isString;
	
	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	exports.isSymbol = isSymbol;
	
	function isUndefined(arg) {
	  return arg === void 0;
	}
	exports.isUndefined = isUndefined;
	
	function isRegExp(re) {
	  return isObject(re) && objectToString(re) === '[object RegExp]';
	}
	exports.isRegExp = isRegExp;
	
	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	exports.isObject = isObject;
	
	function isDate(d) {
	  return isObject(d) && objectToString(d) === '[object Date]';
	}
	exports.isDate = isDate;
	
	function isError(e) {
	  return isObject(e) &&
	      (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	exports.isError = isError;
	
	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	exports.isFunction = isFunction;
	
	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	exports.isPrimitive = isPrimitive;
	
	exports.isBuffer = __webpack_require__(23);
	
	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}
	
	
	function pad(n) {
	  return n < 10 ? '0' + n.toString(10) : n.toString(10);
	}
	
	
	var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
	              'Oct', 'Nov', 'Dec'];
	
	// 26 Feb 16:19:34
	function timestamp() {
	  var d = new Date();
	  var time = [pad(d.getHours()),
	              pad(d.getMinutes()),
	              pad(d.getSeconds())].join(':');
	  return [d.getDate(), months[d.getMonth()], time].join(' ');
	}
	
	
	// log is just a thin wrapper to console.log that prepends a timestamp
	exports.log = function() {
	  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
	};
	
	
	/**
	 * Inherit the prototype methods from one constructor into another.
	 *
	 * The Function.prototype.inherits from lang.js rewritten as a standalone
	 * function (not on Function.prototype). NOTE: If this file is to be loaded
	 * during bootstrapping this function needs to be rewritten using some native
	 * functions as prototype setup using normal JavaScript does not work as
	 * expected during bootstrapping (see mirror.js in r114903).
	 *
	 * @param {function} ctor Constructor function which needs to inherit the
	 *     prototype.
	 * @param {function} superCtor Constructor function to inherit prototype from.
	 */
	exports.inherits = __webpack_require__(24);
	
	exports._extend = function(origin, add) {
	  // Don't do anything if add isn't an object
	  if (!add || !isObject(add)) return origin;
	
	  var keys = Object.keys(add);
	  var i = keys.length;
	  while (i--) {
	    origin[keys[i]] = add[keys[i]];
	  }
	  return origin;
	};
	
	function hasOwnProperty(obj, prop) {
	  return Object.prototype.hasOwnProperty.call(obj, prop);
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(22)))

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


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

	module.exports = function isBuffer(arg) {
	  return arg && typeof arg === 'object'
	    && typeof arg.copy === 'function'
	    && typeof arg.fill === 'function'
	    && typeof arg.readUInt8 === 'function';
	}

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

	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    ctor.prototype = Object.create(superCtor.prototype, {
	      constructor: {
	        value: ctor,
	        enumerable: false,
	        writable: true,
	        configurable: true
	      }
	    });
	  };
	} else {
	  // old school shim for old browsers
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    var TempCtor = function () {}
	    TempCtor.prototype = superCtor.prototype
	    ctor.prototype = new TempCtor()
	    ctor.prototype.constructor = ctor
	  }
	}


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

	
	/**
	 * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
	 * in FIPS 180-2
	 * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
	 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
	 *
	 */
	
	var inherits = __webpack_require__(21).inherits
	
	module.exports = function (Buffer, Hash) {
	
	  var K = [
	      0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
	      0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
	      0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
	      0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
	      0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
	      0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
	      0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
	      0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
	      0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
	      0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
	      0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
	      0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
	      0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
	      0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
	      0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
	      0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
	    ]
	
	  var W = new Array(64)
	
	  function Sha256() {
	    this.init()
	
	    this._w = W //new Array(64)
	
	    Hash.call(this, 16*4, 14*4)
	  }
	
	  inherits(Sha256, Hash)
	
	  Sha256.prototype.init = function () {
	
	    this._a = 0x6a09e667|0
	    this._b = 0xbb67ae85|0
	    this._c = 0x3c6ef372|0
	    this._d = 0xa54ff53a|0
	    this._e = 0x510e527f|0
	    this._f = 0x9b05688c|0
	    this._g = 0x1f83d9ab|0
	    this._h = 0x5be0cd19|0
	
	    this._len = this._s = 0
	
	    return this
	  }
	
	  function S (X, n) {
	    return (X >>> n) | (X << (32 - n));
	  }
	
	  function R (X, n) {
	    return (X >>> n);
	  }
	
	  function Ch (x, y, z) {
	    return ((x & y) ^ ((~x) & z));
	  }
	
	  function Maj (x, y, z) {
	    return ((x & y) ^ (x & z) ^ (y & z));
	  }
	
	  function Sigma0256 (x) {
	    return (S(x, 2) ^ S(x, 13) ^ S(x, 22));
	  }
	
	  function Sigma1256 (x) {
	    return (S(x, 6) ^ S(x, 11) ^ S(x, 25));
	  }
	
	  function Gamma0256 (x) {
	    return (S(x, 7) ^ S(x, 18) ^ R(x, 3));
	  }
	
	  function Gamma1256 (x) {
	    return (S(x, 17) ^ S(x, 19) ^ R(x, 10));
	  }
	
	  Sha256.prototype._update = function(M) {
	
	    var W = this._w
	    var a, b, c, d, e, f, g, h
	    var T1, T2
	
	    a = this._a | 0
	    b = this._b | 0
	    c = this._c | 0
	    d = this._d | 0
	    e = this._e | 0
	    f = this._f | 0
	    g = this._g | 0
	    h = this._h | 0
	
	    for (var j = 0; j < 64; j++) {
	      var w = W[j] = j < 16
	        ? M.readInt32BE(j * 4)
	        : Gamma1256(W[j - 2]) + W[j - 7] + Gamma0256(W[j - 15]) + W[j - 16]
	
	      T1 = h + Sigma1256(e) + Ch(e, f, g) + K[j] + w
	
	      T2 = Sigma0256(a) + Maj(a, b, c);
	      h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2;
	    }
	
	    this._a = (a + this._a) | 0
	    this._b = (b + this._b) | 0
	    this._c = (c + this._c) | 0
	    this._d = (d + this._d) | 0
	    this._e = (e + this._e) | 0
	    this._f = (f + this._f) | 0
	    this._g = (g + this._g) | 0
	    this._h = (h + this._h) | 0
	
	  };
	
	  Sha256.prototype._hash = function () {
	    var H = new Buffer(32)
	
	    H.writeInt32BE(this._a,  0)
	    H.writeInt32BE(this._b,  4)
	    H.writeInt32BE(this._c,  8)
	    H.writeInt32BE(this._d, 12)
	    H.writeInt32BE(this._e, 16)
	    H.writeInt32BE(this._f, 20)
	    H.writeInt32BE(this._g, 24)
	    H.writeInt32BE(this._h, 28)
	
	    return H
	  }
	
	  return Sha256
	
	}


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

	var inherits = __webpack_require__(21).inherits
	
	module.exports = function (Buffer, Hash) {
	  var K = [
	    0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
	    0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
	    0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
	    0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
	    0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
	    0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
	    0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
	    0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
	    0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
	    0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
	    0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
	    0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
	    0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
	    0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
	    0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
	    0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
	    0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
	    0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
	    0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
	    0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
	    0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
	    0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
	    0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
	    0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
	    0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
	    0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
	    0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
	    0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
	    0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
	    0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
	    0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
	    0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
	    0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
	    0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
	    0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
	    0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
	    0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
	    0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
	    0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
	    0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
	  ]
	
	  var W = new Array(160)
	
	  function Sha512() {
	    this.init()
	    this._w = W
	
	    Hash.call(this, 128, 112)
	  }
	
	  inherits(Sha512, Hash)
	
	  Sha512.prototype.init = function () {
	
	    this._a = 0x6a09e667|0
	    this._b = 0xbb67ae85|0
	    this._c = 0x3c6ef372|0
	    this._d = 0xa54ff53a|0
	    this._e = 0x510e527f|0
	    this._f = 0x9b05688c|0
	    this._g = 0x1f83d9ab|0
	    this._h = 0x5be0cd19|0
	
	    this._al = 0xf3bcc908|0
	    this._bl = 0x84caa73b|0
	    this._cl = 0xfe94f82b|0
	    this._dl = 0x5f1d36f1|0
	    this._el = 0xade682d1|0
	    this._fl = 0x2b3e6c1f|0
	    this._gl = 0xfb41bd6b|0
	    this._hl = 0x137e2179|0
	
	    this._len = this._s = 0
	
	    return this
	  }
	
	  function S (X, Xl, n) {
	    return (X >>> n) | (Xl << (32 - n))
	  }
	
	  function Ch (x, y, z) {
	    return ((x & y) ^ ((~x) & z));
	  }
	
	  function Maj (x, y, z) {
	    return ((x & y) ^ (x & z) ^ (y & z));
	  }
	
	  Sha512.prototype._update = function(M) {
	
	    var W = this._w
	    var a, b, c, d, e, f, g, h
	    var al, bl, cl, dl, el, fl, gl, hl
	
	    a = this._a | 0
	    b = this._b | 0
	    c = this._c | 0
	    d = this._d | 0
	    e = this._e | 0
	    f = this._f | 0
	    g = this._g | 0
	    h = this._h | 0
	
	    al = this._al | 0
	    bl = this._bl | 0
	    cl = this._cl | 0
	    dl = this._dl | 0
	    el = this._el | 0
	    fl = this._fl | 0
	    gl = this._gl | 0
	    hl = this._hl | 0
	
	    for (var i = 0; i < 80; i++) {
	      var j = i * 2
	
	      var Wi, Wil
	
	      if (i < 16) {
	        Wi = W[j] = M.readInt32BE(j * 4)
	        Wil = W[j + 1] = M.readInt32BE(j * 4 + 4)
	
	      } else {
	        var x  = W[j - 15*2]
	        var xl = W[j - 15*2 + 1]
	        var gamma0  = S(x, xl, 1) ^ S(x, xl, 8) ^ (x >>> 7)
	        var gamma0l = S(xl, x, 1) ^ S(xl, x, 8) ^ S(xl, x, 7)
	
	        x  = W[j - 2*2]
	        xl = W[j - 2*2 + 1]
	        var gamma1  = S(x, xl, 19) ^ S(xl, x, 29) ^ (x >>> 6)
	        var gamma1l = S(xl, x, 19) ^ S(x, xl, 29) ^ S(xl, x, 6)
	
	        // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
	        var Wi7  = W[j - 7*2]
	        var Wi7l = W[j - 7*2 + 1]
	
	        var Wi16  = W[j - 16*2]
	        var Wi16l = W[j - 16*2 + 1]
	
	        Wil = gamma0l + Wi7l
	        Wi  = gamma0  + Wi7 + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0)
	        Wil = Wil + gamma1l
	        Wi  = Wi  + gamma1  + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0)
	        Wil = Wil + Wi16l
	        Wi  = Wi  + Wi16 + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0)
	
	        W[j] = Wi
	        W[j + 1] = Wil
	      }
	
	      var maj = Maj(a, b, c)
	      var majl = Maj(al, bl, cl)
	
	      var sigma0h = S(a, al, 28) ^ S(al, a, 2) ^ S(al, a, 7)
	      var sigma0l = S(al, a, 28) ^ S(a, al, 2) ^ S(a, al, 7)
	      var sigma1h = S(e, el, 14) ^ S(e, el, 18) ^ S(el, e, 9)
	      var sigma1l = S(el, e, 14) ^ S(el, e, 18) ^ S(e, el, 9)
	
	      // t1 = h + sigma1 + ch + K[i] + W[i]
	      var Ki = K[j]
	      var Kil = K[j + 1]
	
	      var ch = Ch(e, f, g)
	      var chl = Ch(el, fl, gl)
	
	      var t1l = hl + sigma1l
	      var t1 = h + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0)
	      t1l = t1l + chl
	      t1 = t1 + ch + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0)
	      t1l = t1l + Kil
	      t1 = t1 + Ki + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0)
	      t1l = t1l + Wil
	      t1 = t1 + Wi + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0)
	
	      // t2 = sigma0 + maj
	      var t2l = sigma0l + majl
	      var t2 = sigma0h + maj + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0)
	
	      h  = g
	      hl = gl
	      g  = f
	      gl = fl
	      f  = e
	      fl = el
	      el = (dl + t1l) | 0
	      e  = (d + t1 + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0
	      d  = c
	      dl = cl
	      c  = b
	      cl = bl
	      b  = a
	      bl = al
	      al = (t1l + t2l) | 0
	      a  = (t1 + t2 + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0
	    }
	
	    this._al = (this._al + al) | 0
	    this._bl = (this._bl + bl) | 0
	    this._cl = (this._cl + cl) | 0
	    this._dl = (this._dl + dl) | 0
	    this._el = (this._el + el) | 0
	    this._fl = (this._fl + fl) | 0
	    this._gl = (this._gl + gl) | 0
	    this._hl = (this._hl + hl) | 0
	
	    this._a = (this._a + a + ((this._al >>> 0) < (al >>> 0) ? 1 : 0)) | 0
	    this._b = (this._b + b + ((this._bl >>> 0) < (bl >>> 0) ? 1 : 0)) | 0
	    this._c = (this._c + c + ((this._cl >>> 0) < (cl >>> 0) ? 1 : 0)) | 0
	    this._d = (this._d + d + ((this._dl >>> 0) < (dl >>> 0) ? 1 : 0)) | 0
	    this._e = (this._e + e + ((this._el >>> 0) < (el >>> 0) ? 1 : 0)) | 0
	    this._f = (this._f + f + ((this._fl >>> 0) < (fl >>> 0) ? 1 : 0)) | 0
	    this._g = (this._g + g + ((this._gl >>> 0) < (gl >>> 0) ? 1 : 0)) | 0
	    this._h = (this._h + h + ((this._hl >>> 0) < (hl >>> 0) ? 1 : 0)) | 0
	  }
	
	  Sha512.prototype._hash = function () {
	    var H = new Buffer(64)
	
	    function writeInt64BE(h, l, offset) {
	      H.writeInt32BE(h, offset)
	      H.writeInt32BE(l, offset + 4)
	    }
	
	    writeInt64BE(this._a, this._al, 0)
	    writeInt64BE(this._b, this._bl, 8)
	    writeInt64BE(this._c, this._cl, 16)
	    writeInt64BE(this._d, this._dl, 24)
	    writeInt64BE(this._e, this._el, 32)
	    writeInt64BE(this._f, this._fl, 40)
	    writeInt64BE(this._g, this._gl, 48)
	    writeInt64BE(this._h, this._hl, 56)
	
	    return H
	  }
	
	  return Sha512
	
	}


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

	/*
	 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
	 * Digest Algorithm, as defined in RFC 1321.
	 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
	 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
	 * Distributed under the BSD License
	 * See http://pajhome.org.uk/crypt/md5 for more info.
	 */
	
	var helpers = __webpack_require__(28);
	
	/*
	 * Calculate the MD5 of an array of little-endian words, and a bit length
	 */
	function core_md5(x, len)
	{
	  /* append padding */
	  x[len >> 5] |= 0x80 << ((len) % 32);
	  x[(((len + 64) >>> 9) << 4) + 14] = len;
	
	  var a =  1732584193;
	  var b = -271733879;
	  var c = -1732584194;
	  var d =  271733878;
	
	  for(var i = 0; i < x.length; i += 16)
	  {
	    var olda = a;
	    var oldb = b;
	    var oldc = c;
	    var oldd = d;
	
	    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
	    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
	    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
	    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
	    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
	    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
	    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
	    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
	    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
	    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
	    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
	    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
	    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
	    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
	    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
	    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
	
	    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
	    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
	    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
	    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
	    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
	    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
	    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
	    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
	    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
	    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
	    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
	    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
	    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
	    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
	    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
	    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
	
	    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
	    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
	    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
	    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
	    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
	    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
	    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
	    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
	    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
	    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
	    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
	    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
	    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
	    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
	    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
	    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
	
	    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
	    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
	    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
	    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
	    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
	    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
	    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
	    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
	    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
	    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
	    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
	    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
	    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
	    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
	    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
	    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
	
	    a = safe_add(a, olda);
	    b = safe_add(b, oldb);
	    c = safe_add(c, oldc);
	    d = safe_add(d, oldd);
	  }
	  return Array(a, b, c, d);
	
	}
	
	/*
	 * These functions implement the four basic operations the algorithm uses.
	 */
	function md5_cmn(q, a, b, x, s, t)
	{
	  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
	}
	function md5_ff(a, b, c, d, x, s, t)
	{
	  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
	}
	function md5_gg(a, b, c, d, x, s, t)
	{
	  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
	}
	function md5_hh(a, b, c, d, x, s, t)
	{
	  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
	}
	function md5_ii(a, b, c, d, x, s, t)
	{
	  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
	}
	
	/*
	 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
	 * to work around bugs in some JS interpreters.
	 */
	function safe_add(x, y)
	{
	  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
	  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
	  return (msw << 16) | (lsw & 0xFFFF);
	}
	
	/*
	 * Bitwise rotate a 32-bit number to the left.
	 */
	function bit_rol(num, cnt)
	{
	  return (num << cnt) | (num >>> (32 - cnt));
	}
	
	module.exports = function md5(buf) {
	  return helpers.hash(buf, core_md5, 16);
	};


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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var intSize = 4;
	var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0);
	var chrsz = 8;
	
	function toArray(buf, bigEndian) {
	  if ((buf.length % intSize) !== 0) {
	    var len = buf.length + (intSize - (buf.length % intSize));
	    buf = Buffer.concat([buf, zeroBuffer], len);
	  }
	
	  var arr = [];
	  var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE;
	  for (var i = 0; i < buf.length; i += intSize) {
	    arr.push(fn.call(buf, i));
	  }
	  return arr;
	}
	
	function toBuffer(arr, size, bigEndian) {
	  var buf = new Buffer(size);
	  var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE;
	  for (var i = 0; i < arr.length; i++) {
	    fn.call(buf, arr[i], i * 4, true);
	  }
	  return buf;
	}
	
	function hash(buf, fn, hashSize, bigEndian) {
	  if (!Buffer.isBuffer(buf)) buf = new Buffer(buf);
	  var arr = fn(toArray(buf, bigEndian), buf.length * chrsz);
	  return toBuffer(arr, hashSize, bigEndian);
	}
	
	module.exports = { hash: hash };
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {
	module.exports = ripemd160
	
	
	
	/*
	CryptoJS v3.1.2
	code.google.com/p/crypto-js
	(c) 2009-2013 by Jeff Mott. All rights reserved.
	code.google.com/p/crypto-js/wiki/License
	*/
	/** @preserve
	(c) 2012 by Cédric Mesnil. All rights reserved.
	
	Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
	
	    - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
	    - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
	
	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
	*/
	
	// Constants table
	var zl = [
	    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
	    7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
	    3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
	    1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
	    4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13];
	var zr = [
	    5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
	    6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
	    15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
	    8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
	    12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11];
	var sl = [
	     11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
	    7, 6,   8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
	    11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
	      11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
	    9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6 ];
	var sr = [
	    8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
	    9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
	    9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
	    15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
	    8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11 ];
	
	var hl =  [ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E];
	var hr =  [ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000];
	
	var bytesToWords = function (bytes) {
	  var words = [];
	  for (var i = 0, b = 0; i < bytes.length; i++, b += 8) {
	    words[b >>> 5] |= bytes[i] << (24 - b % 32);
	  }
	  return words;
	};
	
	var wordsToBytes = function (words) {
	  var bytes = [];
	  for (var b = 0; b < words.length * 32; b += 8) {
	    bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
	  }
	  return bytes;
	};
	
	var processBlock = function (H, M, offset) {
	
	  // Swap endian
	  for (var i = 0; i < 16; i++) {
	    var offset_i = offset + i;
	    var M_offset_i = M[offset_i];
	
	    // Swap
	    M[offset_i] = (
	        (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |
	        (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)
	    );
	  }
	
	  // Working variables
	  var al, bl, cl, dl, el;
	  var ar, br, cr, dr, er;
	
	  ar = al = H[0];
	  br = bl = H[1];
	  cr = cl = H[2];
	  dr = dl = H[3];
	  er = el = H[4];
	  // Computation
	  var t;
	  for (var i = 0; i < 80; i += 1) {
	    t = (al +  M[offset+zl[i]])|0;
	    if (i<16){
	        t +=  f1(bl,cl,dl) + hl[0];
	    } else if (i<32) {
	        t +=  f2(bl,cl,dl) + hl[1];
	    } else if (i<48) {
	        t +=  f3(bl,cl,dl) + hl[2];
	    } else if (i<64) {
	        t +=  f4(bl,cl,dl) + hl[3];
	    } else {// if (i<80) {
	        t +=  f5(bl,cl,dl) + hl[4];
	    }
	    t = t|0;
	    t =  rotl(t,sl[i]);
	    t = (t+el)|0;
	    al = el;
	    el = dl;
	    dl = rotl(cl, 10);
	    cl = bl;
	    bl = t;
	
	    t = (ar + M[offset+zr[i]])|0;
	    if (i<16){
	        t +=  f5(br,cr,dr) + hr[0];
	    } else if (i<32) {
	        t +=  f4(br,cr,dr) + hr[1];
	    } else if (i<48) {
	        t +=  f3(br,cr,dr) + hr[2];
	    } else if (i<64) {
	        t +=  f2(br,cr,dr) + hr[3];
	    } else {// if (i<80) {
	        t +=  f1(br,cr,dr) + hr[4];
	    }
	    t = t|0;
	    t =  rotl(t,sr[i]) ;
	    t = (t+er)|0;
	    ar = er;
	    er = dr;
	    dr = rotl(cr, 10);
	    cr = br;
	    br = t;
	  }
	  // Intermediate hash value
	  t    = (H[1] + cl + dr)|0;
	  H[1] = (H[2] + dl + er)|0;
	  H[2] = (H[3] + el + ar)|0;
	  H[3] = (H[4] + al + br)|0;
	  H[4] = (H[0] + bl + cr)|0;
	  H[0] =  t;
	};
	
	function f1(x, y, z) {
	  return ((x) ^ (y) ^ (z));
	}
	
	function f2(x, y, z) {
	  return (((x)&(y)) | ((~x)&(z)));
	}
	
	function f3(x, y, z) {
	  return (((x) | (~(y))) ^ (z));
	}
	
	function f4(x, y, z) {
	  return (((x) & (z)) | ((y)&(~(z))));
	}
	
	function f5(x, y, z) {
	  return ((x) ^ ((y) |(~(z))));
	}
	
	function rotl(x,n) {
	  return (x<<n) | (x>>>(32-n));
	}
	
	function ripemd160(message) {
	  var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
	
	  if (typeof message == 'string')
	    message = new Buffer(message, 'utf8');
	
	  var m = bytesToWords(message);
	
	  var nBitsLeft = message.length * 8;
	  var nBitsTotal = message.length * 8;
	
	  // Add padding
	  m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
	  m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
	      (((nBitsTotal << 8)  | (nBitsTotal >>> 24)) & 0x00ff00ff) |
	      (((nBitsTotal << 24) | (nBitsTotal >>> 8))  & 0xff00ff00)
	  );
	
	  for (var i=0 ; i<m.length; i += 16) {
	    processBlock(H, m, i);
	  }
	
	  // Swap endian
	  for (var i = 0; i < 5; i++) {
	      // Shortcut
	    var H_i = H[i];
	
	    // Swap
	    H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |
	          (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);
	  }
	
	  var digestbytes = wordsToBytes(H);
	  return new Buffer(digestbytes);
	}
	
	
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var createHash = __webpack_require__(17)
	
	var zeroBuffer = new Buffer(128)
	zeroBuffer.fill(0)
	
	module.exports = Hmac
	
	function Hmac (alg, key) {
	  if(!(this instanceof Hmac)) return new Hmac(alg, key)
	  this._opad = opad
	  this._alg = alg
	
	  var blocksize = (alg === 'sha512') ? 128 : 64
	
	  key = this._key = !Buffer.isBuffer(key) ? new Buffer(key) : key
	
	  if(key.length > blocksize) {
	    key = createHash(alg).update(key).digest()
	  } else if(key.length < blocksize) {
	    key = Buffer.concat([key, zeroBuffer], blocksize)
	  }
	
	  var ipad = this._ipad = new Buffer(blocksize)
	  var opad = this._opad = new Buffer(blocksize)
	
	  for(var i = 0; i < blocksize; i++) {
	    ipad[i] = key[i] ^ 0x36
	    opad[i] = key[i] ^ 0x5C
	  }
	
	  this._hash = createHash(alg).update(ipad)
	}
	
	Hmac.prototype.update = function (data, enc) {
	  this._hash.update(data, enc)
	  return this
	}
	
	Hmac.prototype.digest = function (enc) {
	  var h = this._hash.digest()
	  return createHash(this._alg).update(this._opad).update(h).digest(enc)
	}
	
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	var pbkdf2Export = __webpack_require__(32)
	
	module.exports = function (crypto, exports) {
	  exports = exports || {}
	
	  var exported = pbkdf2Export(crypto)
	
	  exports.pbkdf2 = exported.pbkdf2
	  exports.pbkdf2Sync = exported.pbkdf2Sync
	
	  return exports
	}


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

	/* WEBPACK VAR INJECTION */(function(Buffer) {module.exports = function(crypto) {
	  function pbkdf2(password, salt, iterations, keylen, digest, callback) {
	    if ('function' === typeof digest) {
	      callback = digest
	      digest = undefined
	    }
	
	    if ('function' !== typeof callback)
	      throw new Error('No callback provided to pbkdf2')
	
	    setTimeout(function() {
	      var result
	
	      try {
	        result = pbkdf2Sync(password, salt, iterations, keylen, digest)
	      } catch (e) {
	        return callback(e)
	      }
	
	      callback(undefined, result)
	    })
	  }
	
	  function pbkdf2Sync(password, salt, iterations, keylen, digest) {
	    if ('number' !== typeof iterations)
	      throw new TypeError('Iterations not a number')
	
	    if (iterations < 0)
	      throw new TypeError('Bad iterations')
	
	    if ('number' !== typeof keylen)
	      throw new TypeError('Key length not a number')
	
	    if (keylen < 0)
	      throw new TypeError('Bad key length')
	
	    digest = digest || 'sha1'
	
	    if (!Buffer.isBuffer(password)) password = new Buffer(password)
	    if (!Buffer.isBuffer(salt)) salt = new Buffer(salt)
	
	    var hLen, l = 1, r, T
	    var DK = new Buffer(keylen)
	    var block1 = new Buffer(salt.length + 4)
	    salt.copy(block1, 0, 0, salt.length)
	
	    for (var i = 1; i <= l; i++) {
	      block1.writeUInt32BE(i, salt.length)
	
	      var U = crypto.createHmac(digest, password).update(block1).digest()
	
	      if (!hLen) {
	        hLen = U.length
	        T = new Buffer(hLen)
	        l = Math.ceil(keylen / hLen)
	        r = keylen - (l - 1) * hLen
	
	        if (keylen > (Math.pow(2, 32) - 1) * hLen)
	          throw new TypeError('keylen exceeds maximum length')
	      }
	
	      U.copy(T, 0, 0, hLen)
	
	      for (var j = 1; j < iterations; j++) {
	        U = crypto.createHmac(digest, password).update(U).digest()
	
	        for (var k = 0; k < hLen; k++) {
	          T[k] ^= U[k]
	        }
	      }
	
	      var destPos = (i - 1) * hLen
	      var len = (i == l ? r : hLen)
	      T.copy(DK, destPos, 0, len)
	    }
	
	    return DK
	  }
	
	  return {
	    pbkdf2: pbkdf2,
	    pbkdf2Sync: pbkdf2Sync
	  }
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	module.exports = function (crypto, exports) {
	  exports = exports || {};
	  var ciphers = __webpack_require__(34)(crypto);
	  exports.createCipher = ciphers.createCipher;
	  exports.createCipheriv = ciphers.createCipheriv;
	  var deciphers = __webpack_require__(70)(crypto);
	  exports.createDecipher = deciphers.createDecipher;
	  exports.createDecipheriv = deciphers.createDecipheriv;
	  var modes = __webpack_require__(61);
	  function listCiphers () {
	    return Object.keys(modes);
	  }
	  exports.listCiphers = listCiphers;
	};
	


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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var aes = __webpack_require__(35);
	var Transform = __webpack_require__(36);
	var inherits = __webpack_require__(39);
	var modes = __webpack_require__(61);
	var ebtk = __webpack_require__(62);
	var StreamCipher = __webpack_require__(63);
	inherits(Cipher, Transform);
	function Cipher(mode, key, iv) {
	  if (!(this instanceof Cipher)) {
	    return new Cipher(mode, key, iv);
	  }
	  Transform.call(this);
	  this._cache = new Splitter();
	  this._cipher = new aes.AES(key);
	  this._prev = new Buffer(iv.length);
	  iv.copy(this._prev);
	  this._mode = mode;
	}
	Cipher.prototype._transform = function (data, _, next) {
	  this._cache.add(data);
	  var chunk;
	  var thing;
	  while ((chunk = this._cache.get())) {
	    thing = this._mode.encrypt(this, chunk);
	    this.push(thing);
	  }
	  next();
	};
	Cipher.prototype._flush = function (next) {
	  var chunk = this._cache.flush();
	  this.push(this._mode.encrypt(this, chunk));
	  this._cipher.scrub();
	  next();
	};
	
	
	function Splitter() {
	   if (!(this instanceof Splitter)) {
	    return new Splitter();
	  }
	  this.cache = new Buffer('');
	}
	Splitter.prototype.add = function (data) {
	  this.cache = Buffer.concat([this.cache, data]);
	};
	
	Splitter.prototype.get = function () {
	  if (this.cache.length > 15) {
	    var out = this.cache.slice(0, 16);
	    this.cache = this.cache.slice(16);
	    return out;
	  }
	  return null;
	};
	Splitter.prototype.flush = function () {
	  var len = 16 - this.cache.length;
	  var padBuff = new Buffer(len);
	
	  var i = -1;
	  while (++i < len) {
	    padBuff.writeUInt8(len, i);
	  }
	  var out = Buffer.concat([this.cache, padBuff]);
	  return out;
	};
	var modelist = {
	  ECB: __webpack_require__(64),
	  CBC: __webpack_require__(65),
	  CFB: __webpack_require__(67),
	  OFB: __webpack_require__(68),
	  CTR: __webpack_require__(69)
	};
	module.exports = function (crypto) {
	  function createCipheriv(suite, password, iv) {
	    var config = modes[suite];
	    if (!config) {
	      throw new TypeError('invalid suite type');
	    }
	    if (typeof iv === 'string') {
	      iv = new Buffer(iv);
	    }
	    if (typeof password === 'string') {
	      password = new Buffer(password);
	    }
	    if (password.length !== config.key/8) {
	      throw new TypeError('invalid key length ' + password.length);
	    }
	    if (iv.length !== config.iv) {
	      throw new TypeError('invalid iv length ' + iv.length);
	    }
	    if (config.type === 'stream') {
	      return new StreamCipher(modelist[config.mode], password, iv);
	    }
	    return new Cipher(modelist[config.mode], password, iv);
	  }
	  function createCipher (suite, password) {
	    var config = modes[suite];
	    if (!config) {
	      throw new TypeError('invalid suite type');
	    }
	    var keys = ebtk(crypto, password, config.key, config.iv);
	    return createCipheriv(suite, keys.key, keys.iv);
	  }
	  return {
	    createCipher: createCipher,
	    createCipheriv: createCipheriv
	  };
	};
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var uint_max = Math.pow(2, 32);
	function fixup_uint32(x) {
	    var ret, x_pos;
	    ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x;
	    return ret;
	}
	function scrub_vec(v) {
	  var i, _i, _ref;
	  for (i = _i = 0, _ref = v.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
	    v[i] = 0;
	  }
	  return false;
	}
	
	function Global() {
	  var i;
	  this.SBOX = [];
	  this.INV_SBOX = [];
	  this.SUB_MIX = (function() {
	    var _i, _results;
	    _results = [];
	    for (i = _i = 0; _i < 4; i = ++_i) {
	      _results.push([]);
	    }
	    return _results;
	  })();
	  this.INV_SUB_MIX = (function() {
	    var _i, _results;
	    _results = [];
	    for (i = _i = 0; _i < 4; i = ++_i) {
	      _results.push([]);
	    }
	    return _results;
	  })();
	  this.init();
	  this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
	}
	
	Global.prototype.init = function() {
	  var d, i, sx, t, x, x2, x4, x8, xi, _i;
	  d = (function() {
	    var _i, _results;
	    _results = [];
	    for (i = _i = 0; _i < 256; i = ++_i) {
	      if (i < 128) {
	        _results.push(i << 1);
	      } else {
	        _results.push((i << 1) ^ 0x11b);
	      }
	    }
	    return _results;
	  })();
	  x = 0;
	  xi = 0;
	  for (i = _i = 0; _i < 256; i = ++_i) {
	    sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
	    sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
	    this.SBOX[x] = sx;
	    this.INV_SBOX[sx] = x;
	    x2 = d[x];
	    x4 = d[x2];
	    x8 = d[x4];
	    t = (d[sx] * 0x101) ^ (sx * 0x1010100);
	    this.SUB_MIX[0][x] = (t << 24) | (t >>> 8);
	    this.SUB_MIX[1][x] = (t << 16) | (t >>> 16);
	    this.SUB_MIX[2][x] = (t << 8) | (t >>> 24);
	    this.SUB_MIX[3][x] = t;
	    t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
	    this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8);
	    this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16);
	    this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24);
	    this.INV_SUB_MIX[3][sx] = t;
	    if (x === 0) {
	      x = xi = 1;
	    } else {
	      x = x2 ^ d[d[d[x8 ^ x2]]];
	      xi ^= d[d[xi]];
	    }
	  }
	  return true;
	};
	
	var G = new Global();
	
	
	AES.blockSize = 4 * 4;
	
	AES.prototype.blockSize = AES.blockSize;
	
	AES.keySize = 256 / 8;
	
	AES.prototype.keySize = AES.keySize;
	
	AES.ivSize = AES.blockSize;
	
	AES.prototype.ivSize = AES.ivSize;
	
	 function bufferToArray(buf) {
	  var len = buf.length/4;
	  var out = new Array(len);
	  var i = -1;
	  while (++i < len) {
	    out[i] = buf.readUInt32BE(i * 4);
	  }
	  return out;
	 }
	function AES(key) {
	  this._key = bufferToArray(key);
	  this._doReset();
	}
	
	AES.prototype._doReset = function() {
	  var invKsRow, keySize, keyWords, ksRow, ksRows, t, _i, _j;
	  keyWords = this._key;
	  keySize = keyWords.length;
	  this._nRounds = keySize + 6;
	  ksRows = (this._nRounds + 1) * 4;
	  this._keySchedule = [];
	  for (ksRow = _i = 0; 0 <= ksRows ? _i < ksRows : _i > ksRows; ksRow = 0 <= ksRows ? ++_i : --_i) {
	    this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % keySize) === 0 ? (t = (t << 8) | (t >>> 24), t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff], t ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t);
	  }
	  this._invKeySchedule = [];
	  for (invKsRow = _j = 0; 0 <= ksRows ? _j < ksRows : _j > ksRows; invKsRow = 0 <= ksRows ? ++_j : --_j) {
	    ksRow = ksRows - invKsRow;
	    t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)];
	    this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]];
	  }
	  return true;
	};
	
	AES.prototype.encryptBlock = function(M) {
	  M = bufferToArray(new Buffer(M));
	  var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX);
	  var buf = new Buffer(16);
	  buf.writeUInt32BE(out[0], 0);
	  buf.writeUInt32BE(out[1], 4);
	  buf.writeUInt32BE(out[2], 8);
	  buf.writeUInt32BE(out[3], 12);
	  return buf;
	};
	
	AES.prototype.decryptBlock = function(M) {
	  M = bufferToArray(new Buffer(M));
	  var temp = [M[3], M[1]];
	  M[1] = temp[0];
	  M[3] = temp[1];
	  var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX);
	  var buf = new Buffer(16);
	  buf.writeUInt32BE(out[0], 0);
	  buf.writeUInt32BE(out[3], 4);
	  buf.writeUInt32BE(out[2], 8);
	  buf.writeUInt32BE(out[1], 12);
	  return buf;
	};
	
	AES.prototype.scrub = function() {
	  scrub_vec(this._keySchedule);
	  scrub_vec(this._invKeySchedule);
	  scrub_vec(this._key);
	};
	
	AES.prototype._doCryptBlock = function(M, keySchedule, SUB_MIX, SBOX) {
	  var ksRow, round, s0, s1, s2, s3, t0, t1, t2, t3, _i, _ref;
	
	  s0 = M[0] ^ keySchedule[0];
	  s1 = M[1] ^ keySchedule[1];
	  s2 = M[2] ^ keySchedule[2];
	  s3 = M[3] ^ keySchedule[3];
	  ksRow = 4;
	  for (round = _i = 1, _ref = this._nRounds; 1 <= _ref ? _i < _ref : _i > _ref; round = 1 <= _ref ? ++_i : --_i) {
	    t0 = SUB_MIX[0][s0 >>> 24] ^ SUB_MIX[1][(s1 >>> 16) & 0xff] ^ SUB_MIX[2][(s2 >>> 8) & 0xff] ^ SUB_MIX[3][s3 & 0xff] ^ keySchedule[ksRow++];
	    t1 = SUB_MIX[0][s1 >>> 24] ^ SUB_MIX[1][(s2 >>> 16) & 0xff] ^ SUB_MIX[2][(s3 >>> 8) & 0xff] ^ SUB_MIX[3][s0 & 0xff] ^ keySchedule[ksRow++];
	    t2 = SUB_MIX[0][s2 >>> 24] ^ SUB_MIX[1][(s3 >>> 16) & 0xff] ^ SUB_MIX[2][(s0 >>> 8) & 0xff] ^ SUB_MIX[3][s1 & 0xff] ^ keySchedule[ksRow++];
	    t3 = SUB_MIX[0][s3 >>> 24] ^ SUB_MIX[1][(s0 >>> 16) & 0xff] ^ SUB_MIX[2][(s1 >>> 8) & 0xff] ^ SUB_MIX[3][s2 & 0xff] ^ keySchedule[ksRow++];
	    s0 = t0;
	    s1 = t1;
	    s2 = t2;
	    s3 = t3;
	  }
	  t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
	  t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
	  t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
	  t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
	  return [
	    fixup_uint32(t0),
	    fixup_uint32(t1),
	    fixup_uint32(t2),
	    fixup_uint32(t3)
	  ];
	
	};
	
	
	
	
	  exports.AES = AES;
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var Transform = __webpack_require__(37).Transform;
	var inherits = __webpack_require__(39);
	
	module.exports = CipherBase;
	inherits(CipherBase, Transform);
	function CipherBase() {
	  Transform.call(this);
	}
	CipherBase.prototype.update = function (data, inputEnd, outputEnc) {
	  this.write(data, inputEnd);
	  var outData = new Buffer('');
	  var chunk;
	  while ((chunk = this.read())) {
	    outData = Buffer.concat([outData, chunk]);
	  }
	  if (outputEnc) {
	    outData = outData.toString(outputEnc);
	  }
	  return outData;
	};
	CipherBase.prototype.final = function (outputEnc) {
	  this.end();
	  var outData = new Buffer('');
	  var chunk;
	  while ((chunk = this.read())) {
	    outData = Buffer.concat([outData, chunk]);
	  }
	  if (outputEnc) {
	    outData = outData.toString(outputEnc);
	  }
	  return outData;
	};
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	module.exports = Stream;
	
	var EE = __webpack_require__(38).EventEmitter;
	var inherits = __webpack_require__(39);
	
	inherits(Stream, EE);
	Stream.Readable = __webpack_require__(40);
	Stream.Writable = __webpack_require__(57);
	Stream.Duplex = __webpack_require__(58);
	Stream.Transform = __webpack_require__(59);
	Stream.PassThrough = __webpack_require__(60);
	
	// Backwards-compat with node 0.4.x
	Stream.Stream = Stream;
	
	
	
	// old-style streams.  Note that the pipe method (the only relevant
	// part of this class) is overridden in the Readable class.
	
	function Stream() {
	  EE.call(this);
	}
	
	Stream.prototype.pipe = function(dest, options) {
	  var source = this;
	
	  function ondata(chunk) {
	    if (dest.writable) {
	      if (false === dest.write(chunk) && source.pause) {
	        source.pause();
	      }
	    }
	  }
	
	  source.on('data', ondata);
	
	  function ondrain() {
	    if (source.readable && source.resume) {
	      source.resume();
	    }
	  }
	
	  dest.on('drain', ondrain);
	
	  // If the 'end' option is not supplied, dest.end() will be called when
	  // source gets the 'end' or 'close' events.  Only dest.end() once.
	  if (!dest._isStdio && (!options || options.end !== false)) {
	    source.on('end', onend);
	    source.on('close', onclose);
	  }
	
	  var didOnEnd = false;
	  function onend() {
	    if (didOnEnd) return;
	    didOnEnd = true;
	
	    dest.end();
	  }
	
	
	  function onclose() {
	    if (didOnEnd) return;
	    didOnEnd = true;
	
	    if (typeof dest.destroy === 'function') dest.destroy();
	  }
	
	  // don't leave dangling pipes when there are errors.
	  function onerror(er) {
	    cleanup();
	    if (EE.listenerCount(this, 'error') === 0) {
	      throw er; // Unhandled stream error in pipe.
	    }
	  }
	
	  source.on('error', onerror);
	  dest.on('error', onerror);
	
	  // remove all the event listeners that were added.
	  function cleanup() {
	    source.removeListener('data', ondata);
	    dest.removeListener('drain', ondrain);
	
	    source.removeListener('end', onend);
	    source.removeListener('close', onclose);
	
	    source.removeListener('error', onerror);
	    dest.removeListener('error', onerror);
	
	    source.removeListener('end', cleanup);
	    source.removeListener('close', cleanup);
	
	    dest.removeListener('close', cleanup);
	  }
	
	  source.on('end', cleanup);
	  source.on('close', cleanup);
	
	  dest.on('close', cleanup);
	
	  dest.emit('pipe', source);
	
	  // Allow for unix-like usage: A.pipe(B).pipe(C)
	  return dest;
	};


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

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	function EventEmitter() {
	  this._events = this._events || {};
	  this._maxListeners = this._maxListeners || undefined;
	}
	module.exports = EventEmitter;
	
	// Backwards-compat with node 0.10.x
	EventEmitter.EventEmitter = EventEmitter;
	
	EventEmitter.prototype._events = undefined;
	EventEmitter.prototype._maxListeners = undefined;
	
	// By default EventEmitters will print a warning if more than 10 listeners are
	// added to it. This is a useful default which helps finding memory leaks.
	EventEmitter.defaultMaxListeners = 10;
	
	// Obviously not all Emitters should be limited to 10. This function allows
	// that to be increased. Set to zero for unlimited.
	EventEmitter.prototype.setMaxListeners = function(n) {
	  if (!isNumber(n) || n < 0 || isNaN(n))
	    throw TypeError('n must be a positive number');
	  this._maxListeners = n;
	  return this;
	};
	
	EventEmitter.prototype.emit = function(type) {
	  var er, handler, len, args, i, listeners;
	
	  if (!this._events)
	    this._events = {};
	
	  // If there is no 'error' event listener then throw.
	  if (type === 'error') {
	    if (!this._events.error ||
	        (isObject(this._events.error) && !this._events.error.length)) {
	      er = arguments[1];
	      if (er instanceof Error) {
	        throw er; // Unhandled 'error' event
	      } else {
	        // At least give some kind of context to the user
	        var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
	        err.context = er;
	        throw err;
	      }
	    }
	  }
	
	  handler = this._events[type];
	
	  if (isUndefined(handler))
	    return false;
	
	  if (isFunction(handler)) {
	    switch (arguments.length) {
	      // fast cases
	      case 1:
	        handler.call(this);
	        break;
	      case 2:
	        handler.call(this, arguments[1]);
	        break;
	      case 3:
	        handler.call(this, arguments[1], arguments[2]);
	        break;
	      // slower
	      default:
	        args = Array.prototype.slice.call(arguments, 1);
	        handler.apply(this, args);
	    }
	  } else if (isObject(handler)) {
	    args = Array.prototype.slice.call(arguments, 1);
	    listeners = handler.slice();
	    len = listeners.length;
	    for (i = 0; i < len; i++)
	      listeners[i].apply(this, args);
	  }
	
	  return true;
	};
	
	EventEmitter.prototype.addListener = function(type, listener) {
	  var m;
	
	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');
	
	  if (!this._events)
	    this._events = {};
	
	  // To avoid recursion in the case that type === "newListener"! Before
	  // adding it to the listeners, first emit "newListener".
	  if (this._events.newListener)
	    this.emit('newListener', type,
	              isFunction(listener.listener) ?
	              listener.listener : listener);
	
	  if (!this._events[type])
	    // Optimize the case of one listener. Don't need the extra array object.
	    this._events[type] = listener;
	  else if (isObject(this._events[type]))
	    // If we've already got an array, just append.
	    this._events[type].push(listener);
	  else
	    // Adding the second element, need to change to array.
	    this._events[type] = [this._events[type], listener];
	
	  // Check for listener leak
	  if (isObject(this._events[type]) && !this._events[type].warned) {
	    if (!isUndefined(this._maxListeners)) {
	      m = this._maxListeners;
	    } else {
	      m = EventEmitter.defaultMaxListeners;
	    }
	
	    if (m && m > 0 && this._events[type].length > m) {
	      this._events[type].warned = true;
	      console.error('(node) warning: possible EventEmitter memory ' +
	                    'leak detected. %d listeners added. ' +
	                    'Use emitter.setMaxListeners() to increase limit.',
	                    this._events[type].length);
	      if (typeof console.trace === 'function') {
	        // not supported in IE 10
	        console.trace();
	      }
	    }
	  }
	
	  return this;
	};
	
	EventEmitter.prototype.on = EventEmitter.prototype.addListener;
	
	EventEmitter.prototype.once = function(type, listener) {
	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');
	
	  var fired = false;
	
	  function g() {
	    this.removeListener(type, g);
	
	    if (!fired) {
	      fired = true;
	      listener.apply(this, arguments);
	    }
	  }
	
	  g.listener = listener;
	  this.on(type, g);
	
	  return this;
	};
	
	// emits a 'removeListener' event iff the listener was removed
	EventEmitter.prototype.removeListener = function(type, listener) {
	  var list, position, length, i;
	
	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');
	
	  if (!this._events || !this._events[type])
	    return this;
	
	  list = this._events[type];
	  length = list.length;
	  position = -1;
	
	  if (list === listener ||
	      (isFunction(list.listener) && list.listener === listener)) {
	    delete this._events[type];
	    if (this._events.removeListener)
	      this.emit('removeListener', type, listener);
	
	  } else if (isObject(list)) {
	    for (i = length; i-- > 0;) {
	      if (list[i] === listener ||
	          (list[i].listener && list[i].listener === listener)) {
	        position = i;
	        break;
	      }
	    }
	
	    if (position < 0)
	      return this;
	
	    if (list.length === 1) {
	      list.length = 0;
	      delete this._events[type];
	    } else {
	      list.splice(position, 1);
	    }
	
	    if (this._events.removeListener)
	      this.emit('removeListener', type, listener);
	  }
	
	  return this;
	};
	
	EventEmitter.prototype.removeAllListeners = function(type) {
	  var key, listeners;
	
	  if (!this._events)
	    return this;
	
	  // not listening for removeListener, no need to emit
	  if (!this._events.removeListener) {
	    if (arguments.length === 0)
	      this._events = {};
	    else if (this._events[type])
	      delete this._events[type];
	    return this;
	  }
	
	  // emit removeListener for all listeners on all events
	  if (arguments.length === 0) {
	    for (key in this._events) {
	      if (key === 'removeListener') continue;
	      this.removeAllListeners(key);
	    }
	    this.removeAllListeners('removeListener');
	    this._events = {};
	    return this;
	  }
	
	  listeners = this._events[type];
	
	  if (isFunction(listeners)) {
	    this.removeListener(type, listeners);
	  } else if (listeners) {
	    // LIFO order
	    while (listeners.length)
	      this.removeListener(type, listeners[listeners.length - 1]);
	  }
	  delete this._events[type];
	
	  return this;
	};
	
	EventEmitter.prototype.listeners = function(type) {
	  var ret;
	  if (!this._events || !this._events[type])
	    ret = [];
	  else if (isFunction(this._events[type]))
	    ret = [this._events[type]];
	  else
	    ret = this._events[type].slice();
	  return ret;
	};
	
	EventEmitter.prototype.listenerCount = function(type) {
	  if (this._events) {
	    var evlistener = this._events[type];
	
	    if (isFunction(evlistener))
	      return 1;
	    else if (evlistener)
	      return evlistener.length;
	  }
	  return 0;
	};
	
	EventEmitter.listenerCount = function(emitter, type) {
	  return emitter.listenerCount(type);
	};
	
	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	
	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	
	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	
	function isUndefined(arg) {
	  return arg === void 0;
	}


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

	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    ctor.prototype = Object.create(superCtor.prototype, {
	      constructor: {
	        value: ctor,
	        enumerable: false,
	        writable: true,
	        configurable: true
	      }
	    });
	  };
	} else {
	  // old school shim for old browsers
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    var TempCtor = function () {}
	    TempCtor.prototype = superCtor.prototype
	    ctor.prototype = new TempCtor()
	    ctor.prototype.constructor = ctor
	  }
	}


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

	exports = module.exports = __webpack_require__(41);
	exports.Stream = exports;
	exports.Readable = exports;
	exports.Writable = __webpack_require__(50);
	exports.Duplex = __webpack_require__(49);
	exports.Transform = __webpack_require__(55);
	exports.PassThrough = __webpack_require__(56);


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

	/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __webpack_require__(42);
	/*</replacement>*/
	
	module.exports = Readable;
	
	/*<replacement>*/
	var isArray = __webpack_require__(14);
	/*</replacement>*/
	
	/*<replacement>*/
	var Duplex;
	/*</replacement>*/
	
	Readable.ReadableState = ReadableState;
	
	/*<replacement>*/
	var EE = __webpack_require__(38).EventEmitter;
	
	var EElistenerCount = function (emitter, type) {
	  return emitter.listeners(type).length;
	};
	/*</replacement>*/
	
	/*<replacement>*/
	var Stream = __webpack_require__(43);
	/*</replacement>*/
	
	// TODO(bmeurer): Change this back to const once hole checks are
	// properly optimized away early in Ignition+TurboFan.
	/*<replacement>*/
	var Buffer = __webpack_require__(44).Buffer;
	var OurUint8Array = global.Uint8Array || function () {};
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
	}
	/*</replacement>*/
	
	/*<replacement>*/
	var util = __webpack_require__(45);
	util.inherits = __webpack_require__(39);
	/*</replacement>*/
	
	/*<replacement>*/
	var debugUtil = __webpack_require__(46);
	var debug = void 0;
	if (debugUtil && debugUtil.debuglog) {
	  debug = debugUtil.debuglog('stream');
	} else {
	  debug = function () {};
	}
	/*</replacement>*/
	
	var BufferList = __webpack_require__(47);
	var destroyImpl = __webpack_require__(48);
	var StringDecoder;
	
	util.inherits(Readable, Stream);
	
	var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
	
	function prependListener(emitter, event, fn) {
	  // Sadly this is not cacheable as some libraries bundle their own
	  // event emitter implementation with them.
	  if (typeof emitter.prependListener === 'function') {
	    return emitter.prependListener(event, fn);
	  } else {
	    // This is a hack to make sure that our error handler is attached before any
	    // userland ones.  NEVER DO THIS. This is here only because this code needs
	    // to continue to work with older versions of Node.js that do not include
	    // the prependListener() method. The goal is to eventually remove this hack.
	    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
	  }
	}
	
	function ReadableState(options, stream) {
	  Duplex = Duplex || __webpack_require__(49);
	
	  options = options || {};
	
	  // object stream flag. Used to make read(n) ignore n and to
	  // make all the buffer merging and length checks go away
	  this.objectMode = !!options.objectMode;
	
	  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
	
	  // the point at which it stops calling _read() to fill the buffer
	  // Note: 0 is a valid value, means "don't call _read preemptively ever"
	  var hwm = options.highWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
	
	  // cast to ints.
	  this.highWaterMark = Math.floor(this.highWaterMark);
	
	  // A linked list is used to store data chunks instead of an array because the
	  // linked list can remove elements from the beginning faster than
	  // array.shift()
	  this.buffer = new BufferList();
	  this.length = 0;
	  this.pipes = null;
	  this.pipesCount = 0;
	  this.flowing = null;
	  this.ended = false;
	  this.endEmitted = false;
	  this.reading = false;
	
	  // a flag to be able to tell if the event 'readable'/'data' is emitted
	  // immediately, or on a later tick.  We set this to true at first, because
	  // any actions that shouldn't happen until "later" should generally also
	  // not happen before the first read call.
	  this.sync = true;
	
	  // whenever we return null, then we set a flag to say
	  // that we're awaiting a 'readable' event emission.
	  this.needReadable = false;
	  this.emittedReadable = false;
	  this.readableListening = false;
	  this.resumeScheduled = false;
	
	  // has it been destroyed
	  this.destroyed = false;
	
	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';
	
	  // the number of writers that are awaiting a drain event in .pipe()s
	  this.awaitDrain = 0;
	
	  // if true, a maybeReadMore has been scheduled
	  this.readingMore = false;
	
	  this.decoder = null;
	  this.encoding = null;
	  if (options.encoding) {
	    if (!StringDecoder) StringDecoder = __webpack_require__(54).StringDecoder;
	    this.decoder = new StringDecoder(options.encoding);
	    this.encoding = options.encoding;
	  }
	}
	
	function Readable(options) {
	  Duplex = Duplex || __webpack_require__(49);
	
	  if (!(this instanceof Readable)) return new Readable(options);
	
	  this._readableState = new ReadableState(options, this);
	
	  // legacy
	  this.readable = true;
	
	  if (options) {
	    if (typeof options.read === 'function') this._read = options.read;
	
	    if (typeof options.destroy === 'function') this._destroy = options.destroy;
	  }
	
	  Stream.call(this);
	}
	
	Object.defineProperty(Readable.prototype, 'destroyed', {
	  get: function () {
	    if (this._readableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._readableState) {
	      return;
	    }
	
	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	  }
	});
	
	Readable.prototype.destroy = destroyImpl.destroy;
	Readable.prototype._undestroy = destroyImpl.undestroy;
	Readable.prototype._destroy = function (err, cb) {
	  this.push(null);
	  cb(err);
	};
	
	// Manually shove something into the read() buffer.
	// This returns true if the highWaterMark has not been hit yet,
	// similar to how Writable.write() returns true if you should
	// write() some more.
	Readable.prototype.push = function (chunk, encoding) {
	  var state = this._readableState;
	  var skipChunkCheck;
	
	  if (!state.objectMode) {
	    if (typeof chunk === 'string') {
	      encoding = encoding || state.defaultEncoding;
	      if (encoding !== state.encoding) {
	        chunk = Buffer.from(chunk, encoding);
	        encoding = '';
	      }
	      skipChunkCheck = true;
	    }
	  } else {
	    skipChunkCheck = true;
	  }
	
	  return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
	};
	
	// Unshift should *always* be something directly out of read()
	Readable.prototype.unshift = function (chunk) {
	  return readableAddChunk(this, chunk, null, true, false);
	};
	
	function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
	  var state = stream._readableState;
	  if (chunk === null) {
	    state.reading = false;
	    onEofChunk(stream, state);
	  } else {
	    var er;
	    if (!skipChunkCheck) er = chunkInvalid(state, chunk);
	    if (er) {
	      stream.emit('error', er);
	    } else if (state.objectMode || chunk && chunk.length > 0) {
	      if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
	        chunk = _uint8ArrayToBuffer(chunk);
	      }
	
	      if (addToFront) {
	        if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true);
	      } else if (state.ended) {
	        stream.emit('error', new Error('stream.push() after EOF'));
	      } else {
	        state.reading = false;
	        if (state.decoder && !encoding) {
	          chunk = state.decoder.write(chunk);
	          if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
	        } else {
	          addChunk(stream, state, chunk, false);
	        }
	      }
	    } else if (!addToFront) {
	      state.reading = false;
	    }
	  }
	
	  return needMoreData(state);
	}
	
	function addChunk(stream, state, chunk, addToFront) {
	  if (state.flowing && state.length === 0 && !state.sync) {
	    stream.emit('data', chunk);
	    stream.read(0);
	  } else {
	    // update the buffer info.
	    state.length += state.objectMode ? 1 : chunk.length;
	    if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
	
	    if (state.needReadable) emitReadable(stream);
	  }
	  maybeReadMore(stream, state);
	}
	
	function chunkInvalid(state, chunk) {
	  var er;
	  if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  return er;
	}
	
	// if it's past the high water mark, we can push in some more.
	// Also, if we have no data yet, we can stand some
	// more bytes.  This is to work around cases where hwm=0,
	// such as the repl.  Also, if the push() triggered a
	// readable event, and the user called read(largeNumber) such that
	// needReadable was set, then we ought to push more, so that another
	// 'readable' event will be triggered.
	function needMoreData(state) {
	  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
	}
	
	Readable.prototype.isPaused = function () {
	  return this._readableState.flowing === false;
	};
	
	// backwards compatibility.
	Readable.prototype.setEncoding = function (enc) {
	  if (!StringDecoder) StringDecoder = __webpack_require__(54).StringDecoder;
	  this._readableState.decoder = new StringDecoder(enc);
	  this._readableState.encoding = enc;
	  return this;
	};
	
	// Don't raise the hwm > 8MB
	var MAX_HWM = 0x800000;
	function computeNewHighWaterMark(n) {
	  if (n >= MAX_HWM) {
	    n = MAX_HWM;
	  } else {
	    // Get the next highest power of 2 to prevent increasing hwm excessively in
	    // tiny amounts
	    n--;
	    n |= n >>> 1;
	    n |= n >>> 2;
	    n |= n >>> 4;
	    n |= n >>> 8;
	    n |= n >>> 16;
	    n++;
	  }
	  return n;
	}
	
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function howMuchToRead(n, state) {
	  if (n <= 0 || state.length === 0 && state.ended) return 0;
	  if (state.objectMode) return 1;
	  if (n !== n) {
	    // Only flow one buffer at a time
	    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
	  }
	  // If we're asking for more than the current hwm, then raise the hwm.
	  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
	  if (n <= state.length) return n;
	  // Don't have enough
	  if (!state.ended) {
	    state.needReadable = true;
	    return 0;
	  }
	  return state.length;
	}
	
	// you can override either this method, or the async _read(n) below.
	Readable.prototype.read = function (n) {
	  debug('read', n);
	  n = parseInt(n, 10);
	  var state = this._readableState;
	  var nOrig = n;
	
	  if (n !== 0) state.emittedReadable = false;
	
	  // if we're doing read(0) to trigger a readable event, but we
	  // already have a bunch of data in the buffer, then just trigger
	  // the 'readable' event and move on.
	  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
	    debug('read: emitReadable', state.length, state.ended);
	    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
	    return null;
	  }
	
	  n = howMuchToRead(n, state);
	
	  // if we've ended, and we're now clear, then finish it up.
	  if (n === 0 && state.ended) {
	    if (state.length === 0) endReadable(this);
	    return null;
	  }
	
	  // All the actual chunk generation logic needs to be
	  // *below* the call to _read.  The reason is that in certain
	  // synthetic stream cases, such as passthrough streams, _read
	  // may be a completely synchronous operation which may change
	  // the state of the read buffer, providing enough data when
	  // before there was *not* enough.
	  //
	  // So, the steps are:
	  // 1. Figure out what the state of things will be after we do
	  // a read from the buffer.
	  //
	  // 2. If that resulting state will trigger a _read, then call _read.
	  // Note that this may be asynchronous, or synchronous.  Yes, it is
	  // deeply ugly to write APIs this way, but that still doesn't mean
	  // that the Readable class should behave improperly, as streams are
	  // designed to be sync/async agnostic.
	  // Take note if the _read call is sync or async (ie, if the read call
	  // has returned yet), so that we know whether or not it's safe to emit
	  // 'readable' etc.
	  //
	  // 3. Actually pull the requested chunks out of the buffer and return.
	
	  // if we need a readable event, then we need to do some reading.
	  var doRead = state.needReadable;
	  debug('need readable', doRead);
	
	  // if we currently have less than the highWaterMark, then also read some
	  if (state.length === 0 || state.length - n < state.highWaterMark) {
	    doRead = true;
	    debug('length less than watermark', doRead);
	  }
	
	  // however, if we've ended, then there's no point, and if we're already
	  // reading, then it's unnecessary.
	  if (state.ended || state.reading) {
	    doRead = false;
	    debug('reading or ended', doRead);
	  } else if (doRead) {
	    debug('do read');
	    state.reading = true;
	    state.sync = true;
	    // if the length is currently zero, then we *need* a readable event.
	    if (state.length === 0) state.needReadable = true;
	    // call internal read method
	    this._read(state.highWaterMark);
	    state.sync = false;
	    // If _read pushed data synchronously, then `reading` will be false,
	    // and we need to re-evaluate how much data we can return to the user.
	    if (!state.reading) n = howMuchToRead(nOrig, state);
	  }
	
	  var ret;
	  if (n > 0) ret = fromList(n, state);else ret = null;
	
	  if (ret === null) {
	    state.needReadable = true;
	    n = 0;
	  } else {
	    state.length -= n;
	  }
	
	  if (state.length === 0) {
	    // If we have nothing in the buffer, then we want to know
	    // as soon as we *do* get something into the buffer.
	    if (!state.ended) state.needReadable = true;
	
	    // If we tried to read() past the EOF, then emit end on the next tick.
	    if (nOrig !== n && state.ended) endReadable(this);
	  }
	
	  if (ret !== null) this.emit('data', ret);
	
	  return ret;
	};
	
	function onEofChunk(stream, state) {
	  if (state.ended) return;
	  if (state.decoder) {
	    var chunk = state.decoder.end();
	    if (chunk && chunk.length) {
	      state.buffer.push(chunk);
	      state.length += state.objectMode ? 1 : chunk.length;
	    }
	  }
	  state.ended = true;
	
	  // emit 'readable' now to make sure it gets picked up.
	  emitReadable(stream);
	}
	
	// Don't emit readable right away in sync mode, because this can trigger
	// another read() call => stack overflow.  This way, it might trigger
	// a nextTick recursion warning, but that's not so bad.
	function emitReadable(stream) {
	  var state = stream._readableState;
	  state.needReadable = false;
	  if (!state.emittedReadable) {
	    debug('emitReadable', state.flowing);
	    state.emittedReadable = true;
	    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
	  }
	}
	
	function emitReadable_(stream) {
	  debug('emit readable');
	  stream.emit('readable');
	  flow(stream);
	}
	
	// at this point, the user has presumably seen the 'readable' event,
	// and called read() to consume some data.  that may have triggered
	// in turn another _read(n) call, in which case reading = true if
	// it's in progress.
	// However, if we're not ended, or reading, and the length < hwm,
	// then go ahead and try to read some more preemptively.
	function maybeReadMore(stream, state) {
	  if (!state.readingMore) {
	    state.readingMore = true;
	    processNextTick(maybeReadMore_, stream, state);
	  }
	}
	
	function maybeReadMore_(stream, state) {
	  var len = state.length;
	  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
	    debug('maybeReadMore read 0');
	    stream.read(0);
	    if (len === state.length)
	      // didn't get any data, stop spinning.
	      break;else len = state.length;
	  }
	  state.readingMore = false;
	}
	
	// abstract method.  to be overridden in specific implementation classes.
	// call cb(er, data) where data is <= n in length.
	// for virtual (non-string, non-buffer) streams, "length" is somewhat
	// arbitrary, and perhaps not very meaningful.
	Readable.prototype._read = function (n) {
	  this.emit('error', new Error('_read() is not implemented'));
	};
	
	Readable.prototype.pipe = function (dest, pipeOpts) {
	  var src = this;
	  var state = this._readableState;
	
	  switch (state.pipesCount) {
	    case 0:
	      state.pipes = dest;
	      break;
	    case 1:
	      state.pipes = [state.pipes, dest];
	      break;
	    default:
	      state.pipes.push(dest);
	      break;
	  }
	  state.pipesCount += 1;
	  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
	
	  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
	
	  var endFn = doEnd ? onend : unpipe;
	  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
	
	  dest.on('unpipe', onunpipe);
	  function onunpipe(readable, unpipeInfo) {
	    debug('onunpipe');
	    if (readable === src) {
	      if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
	        unpipeInfo.hasUnpiped = true;
	        cleanup();
	      }
	    }
	  }
	
	  function onend() {
	    debug('onend');
	    dest.end();
	  }
	
	  // when the dest drains, it reduces the awaitDrain counter
	  // on the source.  This would be more elegant with a .once()
	  // handler in flow(), but adding and removing repeatedly is
	  // too slow.
	  var ondrain = pipeOnDrain(src);
	  dest.on('drain', ondrain);
	
	  var cleanedUp = false;
	  function cleanup() {
	    debug('cleanup');
	    // cleanup event handlers once the pipe is broken
	    dest.removeListener('close', onclose);
	    dest.removeListener('finish', onfinish);
	    dest.removeListener('drain', ondrain);
	    dest.removeListener('error', onerror);
	    dest.removeListener('unpipe', onunpipe);
	    src.removeListener('end', onend);
	    src.removeListener('end', unpipe);
	    src.removeListener('data', ondata);
	
	    cleanedUp = true;
	
	    // if the reader is waiting for a drain event from this
	    // specific writer, then it would cause it to never start
	    // flowing again.
	    // So, if this is awaiting a drain, then we just call it now.
	    // If we don't know, then assume that we are waiting for one.
	    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
	  }
	
	  // If the user pushes more data while we're writing to dest then we'll end up
	  // in ondata again. However, we only want to increase awaitDrain once because
	  // dest will only emit one 'drain' event for the multiple writes.
	  // => Introduce a guard on increasing awaitDrain.
	  var increasedAwaitDrain = false;
	  src.on('data', ondata);
	  function ondata(chunk) {
	    debug('ondata');
	    increasedAwaitDrain = false;
	    var ret = dest.write(chunk);
	    if (false === ret && !increasedAwaitDrain) {
	      // If the user unpiped during `dest.write()`, it is possible
	      // to get stuck in a permanently paused state if that write
	      // also returned false.
	      // => Check whether `dest` is still a piping destination.
	      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
	        debug('false write response, pause', src._readableState.awaitDrain);
	        src._readableState.awaitDrain++;
	        increasedAwaitDrain = true;
	      }
	      src.pause();
	    }
	  }
	
	  // if the dest has an error, then stop piping into it.
	  // however, don't suppress the throwing behavior for this.
	  function onerror(er) {
	    debug('onerror', er);
	    unpipe();
	    dest.removeListener('error', onerror);
	    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
	  }
	
	  // Make sure our error handler is attached before userland ones.
	  prependListener(dest, 'error', onerror);
	
	  // Both close and finish should trigger unpipe, but only once.
	  function onclose() {
	    dest.removeListener('finish', onfinish);
	    unpipe();
	  }
	  dest.once('close', onclose);
	  function onfinish() {
	    debug('onfinish');
	    dest.removeListener('close', onclose);
	    unpipe();
	  }
	  dest.once('finish', onfinish);
	
	  function unpipe() {
	    debug('unpipe');
	    src.unpipe(dest);
	  }
	
	  // tell the dest that it's being piped to
	  dest.emit('pipe', src);
	
	  // start the flow if it hasn't been started already.
	  if (!state.flowing) {
	    debug('pipe resume');
	    src.resume();
	  }
	
	  return dest;
	};
	
	function pipeOnDrain(src) {
	  return function () {
	    var state = src._readableState;
	    debug('pipeOnDrain', state.awaitDrain);
	    if (state.awaitDrain) state.awaitDrain--;
	    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
	      state.flowing = true;
	      flow(src);
	    }
	  };
	}
	
	Readable.prototype.unpipe = function (dest) {
	  var state = this._readableState;
	  var unpipeInfo = { hasUnpiped: false };
	
	  // if we're not piping anywhere, then do nothing.
	  if (state.pipesCount === 0) return this;
	
	  // just one destination.  most common case.
	  if (state.pipesCount === 1) {
	    // passed in one, but it's not the right one.
	    if (dest && dest !== state.pipes) return this;
	
	    if (!dest) dest = state.pipes;
	
	    // got a match.
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	    if (dest) dest.emit('unpipe', this, unpipeInfo);
	    return this;
	  }
	
	  // slow case. multiple pipe destinations.
	
	  if (!dest) {
	    // remove all.
	    var dests = state.pipes;
	    var len = state.pipesCount;
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	
	    for (var i = 0; i < len; i++) {
	      dests[i].emit('unpipe', this, unpipeInfo);
	    }return this;
	  }
	
	  // try to find the right one.
	  var index = indexOf(state.pipes, dest);
	  if (index === -1) return this;
	
	  state.pipes.splice(index, 1);
	  state.pipesCount -= 1;
	  if (state.pipesCount === 1) state.pipes = state.pipes[0];
	
	  dest.emit('unpipe', this, unpipeInfo);
	
	  return this;
	};
	
	// set up data events if they are asked for
	// Ensure readable listeners eventually get something
	Readable.prototype.on = function (ev, fn) {
	  var res = Stream.prototype.on.call(this, ev, fn);
	
	  if (ev === 'data') {
	    // Start flowing on next tick if stream isn't explicitly paused
	    if (this._readableState.flowing !== false) this.resume();
	  } else if (ev === 'readable') {
	    var state = this._readableState;
	    if (!state.endEmitted && !state.readableListening) {
	      state.readableListening = state.needReadable = true;
	      state.emittedReadable = false;
	      if (!state.reading) {
	        processNextTick(nReadingNextTick, this);
	      } else if (state.length) {
	        emitReadable(this);
	      }
	    }
	  }
	
	  return res;
	};
	Readable.prototype.addListener = Readable.prototype.on;
	
	function nReadingNextTick(self) {
	  debug('readable nexttick read 0');
	  self.read(0);
	}
	
	// pause() and resume() are remnants of the legacy readable stream API
	// If the user uses them, then switch into old mode.
	Readable.prototype.resume = function () {
	  var state = this._readableState;
	  if (!state.flowing) {
	    debug('resume');
	    state.flowing = true;
	    resume(this, state);
	  }
	  return this;
	};
	
	function resume(stream, state) {
	  if (!state.resumeScheduled) {
	    state.resumeScheduled = true;
	    processNextTick(resume_, stream, state);
	  }
	}
	
	function resume_(stream, state) {
	  if (!state.reading) {
	    debug('resume read 0');
	    stream.read(0);
	  }
	
	  state.resumeScheduled = false;
	  state.awaitDrain = 0;
	  stream.emit('resume');
	  flow(stream);
	  if (state.flowing && !state.reading) stream.read(0);
	}
	
	Readable.prototype.pause = function () {
	  debug('call pause flowing=%j', this._readableState.flowing);
	  if (false !== this._readableState.flowing) {
	    debug('pause');
	    this._readableState.flowing = false;
	    this.emit('pause');
	  }
	  return this;
	};
	
	function flow(stream) {
	  var state = stream._readableState;
	  debug('flow', state.flowing);
	  while (state.flowing && stream.read() !== null) {}
	}
	
	// wrap an old-style stream as the async data source.
	// This is *not* part of the readable stream interface.
	// It is an ugly unfortunate mess of history.
	Readable.prototype.wrap = function (stream) {
	  var state = this._readableState;
	  var paused = false;
	
	  var self = this;
	  stream.on('end', function () {
	    debug('wrapped end');
	    if (state.decoder && !state.ended) {
	      var chunk = state.decoder.end();
	      if (chunk && chunk.length) self.push(chunk);
	    }
	
	    self.push(null);
	  });
	
	  stream.on('data', function (chunk) {
	    debug('wrapped data');
	    if (state.decoder) chunk = state.decoder.write(chunk);
	
	    // don't skip over falsy values in objectMode
	    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
	
	    var ret = self.push(chunk);
	    if (!ret) {
	      paused = true;
	      stream.pause();
	    }
	  });
	
	  // proxy all the other methods.
	  // important when wrapping filters and duplexes.
	  for (var i in stream) {
	    if (this[i] === undefined && typeof stream[i] === 'function') {
	      this[i] = function (method) {
	        return function () {
	          return stream[method].apply(stream, arguments);
	        };
	      }(i);
	    }
	  }
	
	  // proxy certain important events.
	  for (var n = 0; n < kProxyEvents.length; n++) {
	    stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n]));
	  }
	
	  // when we try to consume some more bytes, simply unpause the
	  // underlying stream.
	  self._read = function (n) {
	    debug('wrapped _read', n);
	    if (paused) {
	      paused = false;
	      stream.resume();
	    }
	  };
	
	  return self;
	};
	
	// exposed for testing purposes only.
	Readable._fromList = fromList;
	
	// Pluck off n bytes from an array of buffers.
	// Length is the combined lengths of all the buffers in the list.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function fromList(n, state) {
	  // nothing buffered
	  if (state.length === 0) return null;
	
	  var ret;
	  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
	    // read it all, truncate the list
	    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
	    state.buffer.clear();
	  } else {
	    // read part of list
	    ret = fromListPartial(n, state.buffer, state.decoder);
	  }
	
	  return ret;
	}
	
	// Extracts only enough buffered data to satisfy the amount requested.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function fromListPartial(n, list, hasStrings) {
	  var ret;
	  if (n < list.head.data.length) {
	    // slice is the same for buffers and strings
	    ret = list.head.data.slice(0, n);
	    list.head.data = list.head.data.slice(n);
	  } else if (n === list.head.data.length) {
	    // first chunk is a perfect match
	    ret = list.shift();
	  } else {
	    // result spans more than one buffer
	    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
	  }
	  return ret;
	}
	
	// Copies a specified amount of characters from the list of buffered data
	// chunks.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function copyFromBufferString(n, list) {
	  var p = list.head;
	  var c = 1;
	  var ret = p.data;
	  n -= ret.length;
	  while (p = p.next) {
	    var str = p.data;
	    var nb = n > str.length ? str.length : n;
	    if (nb === str.length) ret += str;else ret += str.slice(0, n);
	    n -= nb;
	    if (n === 0) {
	      if (nb === str.length) {
	        ++c;
	        if (p.next) list.head = p.next;else list.head = list.tail = null;
	      } else {
	        list.head = p;
	        p.data = str.slice(nb);
	      }
	      break;
	    }
	    ++c;
	  }
	  list.length -= c;
	  return ret;
	}
	
	// Copies a specified amount of bytes from the list of buffered data chunks.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function copyFromBuffer(n, list) {
	  var ret = Buffer.allocUnsafe(n);
	  var p = list.head;
	  var c = 1;
	  p.data.copy(ret);
	  n -= p.data.length;
	  while (p = p.next) {
	    var buf = p.data;
	    var nb = n > buf.length ? buf.length : n;
	    buf.copy(ret, ret.length - n, 0, nb);
	    n -= nb;
	    if (n === 0) {
	      if (nb === buf.length) {
	        ++c;
	        if (p.next) list.head = p.next;else list.head = list.tail = null;
	      } else {
	        list.head = p;
	        p.data = buf.slice(nb);
	      }
	      break;
	    }
	    ++c;
	  }
	  list.length -= c;
	  return ret;
	}
	
	function endReadable(stream) {
	  var state = stream._readableState;
	
	  // If we get here before consuming all the bytes, then that is a
	  // bug in node.  Should never happen.
	  if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');
	
	  if (!state.endEmitted) {
	    state.ended = true;
	    processNextTick(endReadableNT, state, stream);
	  }
	}
	
	function endReadableNT(state, stream) {
	  // Check that we didn't get one last unshift.
	  if (!state.endEmitted && state.length === 0) {
	    state.endEmitted = true;
	    stream.readable = false;
	    stream.emit('end');
	  }
	}
	
	function forEach(xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}
	
	function indexOf(xs, x) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    if (xs[i] === x) return i;
	  }
	  return -1;
	}
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(22)))

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

	/* WEBPACK VAR INJECTION */(function(process) {'use strict';
	
	if (!process.version ||
	    process.version.indexOf('v0.') === 0 ||
	    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
	  module.exports = nextTick;
	} else {
	  module.exports = process.nextTick;
	}
	
	function nextTick(fn, arg1, arg2, arg3) {
	  if (typeof fn !== 'function') {
	    throw new TypeError('"callback" argument must be a function');
	  }
	  var len = arguments.length;
	  var args, i;
	  switch (len) {
	  case 0:
	  case 1:
	    return process.nextTick(fn);
	  case 2:
	    return process.nextTick(function afterTickOne() {
	      fn.call(null, arg1);
	    });
	  case 3:
	    return process.nextTick(function afterTickTwo() {
	      fn.call(null, arg1, arg2);
	    });
	  case 4:
	    return process.nextTick(function afterTickThree() {
	      fn.call(null, arg1, arg2, arg3);
	    });
	  default:
	    args = new Array(len - 1);
	    i = 0;
	    while (i < args.length) {
	      args[i++] = arguments[i];
	    }
	    return process.nextTick(function afterTick() {
	      fn.apply(null, args);
	    });
	  }
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(22)))

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

	module.exports = __webpack_require__(38).EventEmitter;


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

	/* eslint-disable node/no-deprecated-api */
	var buffer = __webpack_require__(12)
	var Buffer = buffer.Buffer
	
	// alternative to using Object.keys for old browsers
	function copyProps (src, dst) {
	  for (var key in src) {
	    dst[key] = src[key]
	  }
	}
	if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
	  module.exports = buffer
	} else {
	  // Copy properties from require('buffer')
	  copyProps(buffer, exports)
	  exports.Buffer = SafeBuffer
	}
	
	function SafeBuffer (arg, encodingOrOffset, length) {
	  return Buffer(arg, encodingOrOffset, length)
	}
	
	// Copy static methods from Buffer
	copyProps(Buffer, SafeBuffer)
	
	SafeBuffer.from = function (arg, encodingOrOffset, length) {
	  if (typeof arg === 'number') {
	    throw new TypeError('Argument must not be a number')
	  }
	  return Buffer(arg, encodingOrOffset, length)
	}
	
	SafeBuffer.alloc = function (size, fill, encoding) {
	  if (typeof size !== 'number') {
	    throw new TypeError('Argument must be a number')
	  }
	  var buf = Buffer(size)
	  if (fill !== undefined) {
	    if (typeof encoding === 'string') {
	      buf.fill(fill, encoding)
	    } else {
	      buf.fill(fill)
	    }
	  } else {
	    buf.fill(0)
	  }
	  return buf
	}
	
	SafeBuffer.allocUnsafe = function (size) {
	  if (typeof size !== 'number') {
	    throw new TypeError('Argument must be a number')
	  }
	  return Buffer(size)
	}
	
	SafeBuffer.allocUnsafeSlow = function (size) {
	  if (typeof size !== 'number') {
	    throw new TypeError('Argument must be a number')
	  }
	  return buffer.SlowBuffer(size)
	}


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

	/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.
	
	function isArray(arg) {
	  if (Array.isArray) {
	    return Array.isArray(arg);
	  }
	  return objectToString(arg) === '[object Array]';
	}
	exports.isArray = isArray;
	
	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	exports.isBoolean = isBoolean;
	
	function isNull(arg) {
	  return arg === null;
	}
	exports.isNull = isNull;
	
	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	exports.isNullOrUndefined = isNullOrUndefined;
	
	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	exports.isNumber = isNumber;
	
	function isString(arg) {
	  return typeof arg === 'string';
	}
	exports.isString = isString;
	
	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	exports.isSymbol = isSymbol;
	
	function isUndefined(arg) {
	  return arg === void 0;
	}
	exports.isUndefined = isUndefined;
	
	function isRegExp(re) {
	  return objectToString(re) === '[object RegExp]';
	}
	exports.isRegExp = isRegExp;
	
	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	exports.isObject = isObject;
	
	function isDate(d) {
	  return objectToString(d) === '[object Date]';
	}
	exports.isDate = isDate;
	
	function isError(e) {
	  return (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	exports.isError = isError;
	
	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	exports.isFunction = isFunction;
	
	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	exports.isPrimitive = isPrimitive;
	
	exports.isBuffer = Buffer.isBuffer;
	
	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* (ignored) */

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

	'use strict';
	
	/*<replacement>*/
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	var Buffer = __webpack_require__(44).Buffer;
	/*</replacement>*/
	
	function copyBuffer(src, target, offset) {
	  src.copy(target, offset);
	}
	
	module.exports = function () {
	  function BufferList() {
	    _classCallCheck(this, BufferList);
	
	    this.head = null;
	    this.tail = null;
	    this.length = 0;
	  }
	
	  BufferList.prototype.push = function push(v) {
	    var entry = { data: v, next: null };
	    if (this.length > 0) this.tail.next = entry;else this.head = entry;
	    this.tail = entry;
	    ++this.length;
	  };
	
	  BufferList.prototype.unshift = function unshift(v) {
	    var entry = { data: v, next: this.head };
	    if (this.length === 0) this.tail = entry;
	    this.head = entry;
	    ++this.length;
	  };
	
	  BufferList.prototype.shift = function shift() {
	    if (this.length === 0) return;
	    var ret = this.head.data;
	    if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
	    --this.length;
	    return ret;
	  };
	
	  BufferList.prototype.clear = function clear() {
	    this.head = this.tail = null;
	    this.length = 0;
	  };
	
	  BufferList.prototype.join = function join(s) {
	    if (this.length === 0) return '';
	    var p = this.head;
	    var ret = '' + p.data;
	    while (p = p.next) {
	      ret += s + p.data;
	    }return ret;
	  };
	
	  BufferList.prototype.concat = function concat(n) {
	    if (this.length === 0) return Buffer.alloc(0);
	    if (this.length === 1) return this.head.data;
	    var ret = Buffer.allocUnsafe(n >>> 0);
	    var p = this.head;
	    var i = 0;
	    while (p) {
	      copyBuffer(p.data, ret, i);
	      i += p.data.length;
	      p = p.next;
	    }
	    return ret;
	  };
	
	  return BufferList;
	}();

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

	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __webpack_require__(42);
	/*</replacement>*/
	
	// undocumented cb() API, needed for core, not for public API
	function destroy(err, cb) {
	  var _this = this;
	
	  var readableDestroyed = this._readableState && this._readableState.destroyed;
	  var writableDestroyed = this._writableState && this._writableState.destroyed;
	
	  if (readableDestroyed || writableDestroyed) {
	    if (cb) {
	      cb(err);
	    } else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
	      processNextTick(emitErrorNT, this, err);
	    }
	    return;
	  }
	
	  // we set destroyed to true before firing error callbacks in order
	  // to make it re-entrance safe in case destroy() is called within callbacks
	
	  if (this._readableState) {
	    this._readableState.destroyed = true;
	  }
	
	  // if this is a duplex stream mark the writable part as destroyed as well
	  if (this._writableState) {
	    this._writableState.destroyed = true;
	  }
	
	  this._destroy(err || null, function (err) {
	    if (!cb && err) {
	      processNextTick(emitErrorNT, _this, err);
	      if (_this._writableState) {
	        _this._writableState.errorEmitted = true;
	      }
	    } else if (cb) {
	      cb(err);
	    }
	  });
	}
	
	function undestroy() {
	  if (this._readableState) {
	    this._readableState.destroyed = false;
	    this._readableState.reading = false;
	    this._readableState.ended = false;
	    this._readableState.endEmitted = false;
	  }
	
	  if (this._writableState) {
	    this._writableState.destroyed = false;
	    this._writableState.ended = false;
	    this._writableState.ending = false;
	    this._writableState.finished = false;
	    this._writableState.errorEmitted = false;
	  }
	}
	
	function emitErrorNT(self, err) {
	  self.emit('error', err);
	}
	
	module.exports = {
	  destroy: destroy,
	  undestroy: undestroy
	};

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

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// a duplex stream is just a stream that is both readable and writable.
	// Since JS doesn't have multiple prototypal inheritance, this class
	// prototypally inherits from Readable, and then parasitically from
	// Writable.
	
	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __webpack_require__(42);
	/*</replacement>*/
	
	/*<replacement>*/
	var objectKeys = Object.keys || function (obj) {
	  var keys = [];
	  for (var key in obj) {
	    keys.push(key);
	  }return keys;
	};
	/*</replacement>*/
	
	module.exports = Duplex;
	
	/*<replacement>*/
	var util = __webpack_require__(45);
	util.inherits = __webpack_require__(39);
	/*</replacement>*/
	
	var Readable = __webpack_require__(41);
	var Writable = __webpack_require__(50);
	
	util.inherits(Duplex, Readable);
	
	var keys = objectKeys(Writable.prototype);
	for (var v = 0; v < keys.length; v++) {
	  var method = keys[v];
	  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
	}
	
	function Duplex(options) {
	  if (!(this instanceof Duplex)) return new Duplex(options);
	
	  Readable.call(this, options);
	  Writable.call(this, options);
	
	  if (options && options.readable === false) this.readable = false;
	
	  if (options && options.writable === false) this.writable = false;
	
	  this.allowHalfOpen = true;
	  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
	
	  this.once('end', onend);
	}
	
	// the no-half-open enforcer
	function onend() {
	  // if we allow half-open state, or if the writable side ended,
	  // then we're ok.
	  if (this.allowHalfOpen || this._writableState.ended) return;
	
	  // no more data can be written.
	  // But allow more writes to happen in this tick.
	  processNextTick(onEndNT, this);
	}
	
	function onEndNT(self) {
	  self.end();
	}
	
	Object.defineProperty(Duplex.prototype, 'destroyed', {
	  get: function () {
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed && this._writableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return;
	    }
	
	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	    this._writableState.destroyed = value;
	  }
	});
	
	Duplex.prototype._destroy = function (err, cb) {
	  this.push(null);
	  this.end();
	
	  processNextTick(cb, err);
	};
	
	function forEach(xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}

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

	/* WEBPACK VAR INJECTION */(function(process, setImmediate, global) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// A bit simpler than readable streams.
	// Implement an async ._write(chunk, encoding, cb), and it'll handle all
	// the drain event emission and buffering.
	
	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __webpack_require__(42);
	/*</replacement>*/
	
	module.exports = Writable;
	
	/* <replacement> */
	function WriteReq(chunk, encoding, cb) {
	  this.chunk = chunk;
	  this.encoding = encoding;
	  this.callback = cb;
	  this.next = null;
	}
	
	// It seems a linked list but it is not
	// there will be only 2 of these for each stream
	function CorkedRequest(state) {
	  var _this = this;
	
	  this.next = null;
	  this.entry = null;
	  this.finish = function () {
	    onCorkedFinish(_this, state);
	  };
	}
	/* </replacement> */
	
	/*<replacement>*/
	var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
	/*</replacement>*/
	
	/*<replacement>*/
	var Duplex;
	/*</replacement>*/
	
	Writable.WritableState = WritableState;
	
	/*<replacement>*/
	var util = __webpack_require__(45);
	util.inherits = __webpack_require__(39);
	/*</replacement>*/
	
	/*<replacement>*/
	var internalUtil = {
	  deprecate: __webpack_require__(53)
	};
	/*</replacement>*/
	
	/*<replacement>*/
	var Stream = __webpack_require__(43);
	/*</replacement>*/
	
	/*<replacement>*/
	var Buffer = __webpack_require__(44).Buffer;
	var OurUint8Array = global.Uint8Array || function () {};
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
	}
	/*</replacement>*/
	
	var destroyImpl = __webpack_require__(48);
	
	util.inherits(Writable, Stream);
	
	function nop() {}
	
	function WritableState(options, stream) {
	  Duplex = Duplex || __webpack_require__(49);
	
	  options = options || {};
	
	  // object stream flag to indicate whether or not this stream
	  // contains buffers or objects.
	  this.objectMode = !!options.objectMode;
	
	  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
	
	  // the point at which write() starts returning false
	  // Note: 0 is a valid value, means that we always return false if
	  // the entire buffer is not flushed immediately on write()
	  var hwm = options.highWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
	
	  // cast to ints.
	  this.highWaterMark = Math.floor(this.highWaterMark);
	
	  // if _final has been called
	  this.finalCalled = false;
	
	  // drain event flag.
	  this.needDrain = false;
	  // at the start of calling end()
	  this.ending = false;
	  // when end() has been called, and returned
	  this.ended = false;
	  // when 'finish' is emitted
	  this.finished = false;
	
	  // has it been destroyed
	  this.destroyed = false;
	
	  // should we decode strings into buffers before passing to _write?
	  // this is here so that some node-core streams can optimize string
	  // handling at a lower level.
	  var noDecode = options.decodeStrings === false;
	  this.decodeStrings = !noDecode;
	
	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';
	
	  // not an actual buffer we keep track of, but a measurement
	  // of how much we're waiting to get pushed to some underlying
	  // socket or file.
	  this.length = 0;
	
	  // a flag to see when we're in the middle of a write.
	  this.writing = false;
	
	  // when true all writes will be buffered until .uncork() call
	  this.corked = 0;
	
	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;
	
	  // a flag to know if we're processing previously buffered items, which
	  // may call the _write() callback in the same tick, so that we don't
	  // end up in an overlapped onwrite situation.
	  this.bufferProcessing = false;
	
	  // the callback that's passed to _write(chunk,cb)
	  this.onwrite = function (er) {
	    onwrite(stream, er);
	  };
	
	  // the callback that the user supplies to write(chunk,encoding,cb)
	  this.writecb = null;
	
	  // the amount that is being written when _write is called.
	  this.writelen = 0;
	
	  this.bufferedRequest = null;
	  this.lastBufferedRequest = null;
	
	  // number of pending user-supplied write callbacks
	  // this must be 0 before 'finish' can be emitted
	  this.pendingcb = 0;
	
	  // emit prefinish if the only thing we're waiting for is _write cbs
	  // This is relevant for synchronous Transform streams
	  this.prefinished = false;
	
	  // True if the error was already emitted and should not be thrown again
	  this.errorEmitted = false;
	
	  // count buffered requests
	  this.bufferedRequestCount = 0;
	
	  // allocate the first CorkedRequest, there is always
	  // one allocated and free to use, and we maintain at most two
	  this.corkedRequestsFree = new CorkedRequest(this);
	}
	
	WritableState.prototype.getBuffer = function getBuffer() {
	  var current = this.bufferedRequest;
	  var out = [];
	  while (current) {
	    out.push(current);
	    current = current.next;
	  }
	  return out;
	};
	
	(function () {
	  try {
	    Object.defineProperty(WritableState.prototype, 'buffer', {
	      get: internalUtil.deprecate(function () {
	        return this.getBuffer();
	      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
	    });
	  } catch (_) {}
	})();
	
	// Test _writableState for inheritance to account for Duplex streams,
	// whose prototype chain only points to Readable.
	var realHasInstance;
	if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
	  realHasInstance = Function.prototype[Symbol.hasInstance];
	  Object.defineProperty(Writable, Symbol.hasInstance, {
	    value: function (object) {
	      if (realHasInstance.call(this, object)) return true;
	
	      return object && object._writableState instanceof WritableState;
	    }
	  });
	} else {
	  realHasInstance = function (object) {
	    return object instanceof this;
	  };
	}
	
	function Writable(options) {
	  Duplex = Duplex || __webpack_require__(49);
	
	  // Writable ctor is applied to Duplexes, too.
	  // `realHasInstance` is necessary because using plain `instanceof`
	  // would return false, as no `_writableState` property is attached.
	
	  // Trying to use the custom `instanceof` for Writable here will also break the
	  // Node.js LazyTransform implementation, which has a non-trivial getter for
	  // `_writableState` that would lead to infinite recursion.
	  if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
	    return new Writable(options);
	  }
	
	  this._writableState = new WritableState(options, this);
	
	  // legacy.
	  this.writable = true;
	
	  if (options) {
	    if (typeof options.write === 'function') this._write = options.write;
	
	    if (typeof options.writev === 'function') this._writev = options.writev;
	
	    if (typeof options.destroy === 'function') this._destroy = options.destroy;
	
	    if (typeof options.final === 'function') this._final = options.final;
	  }
	
	  Stream.call(this);
	}
	
	// Otherwise people can pipe Writable streams, which is just wrong.
	Writable.prototype.pipe = function () {
	  this.emit('error', new Error('Cannot pipe, not readable'));
	};
	
	function writeAfterEnd(stream, cb) {
	  var er = new Error('write after end');
	  // TODO: defer error events consistently everywhere, not just the cb
	  stream.emit('error', er);
	  processNextTick(cb, er);
	}
	
	// Checks that a user-supplied chunk is valid, especially for the particular
	// mode the stream is in. Currently this means that `null` is never accepted
	// and undefined/non-string values are only allowed in object mode.
	function validChunk(stream, state, chunk, cb) {
	  var valid = true;
	  var er = false;
	
	  if (chunk === null) {
	    er = new TypeError('May not write null values to stream');
	  } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  if (er) {
	    stream.emit('error', er);
	    processNextTick(cb, er);
	    valid = false;
	  }
	  return valid;
	}
	
	Writable.prototype.write = function (chunk, encoding, cb) {
	  var state = this._writableState;
	  var ret = false;
	  var isBuf = _isUint8Array(chunk) && !state.objectMode;
	
	  if (isBuf && !Buffer.isBuffer(chunk)) {
	    chunk = _uint8ArrayToBuffer(chunk);
	  }
	
	  if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }
	
	  if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
	
	  if (typeof cb !== 'function') cb = nop;
	
	  if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
	    state.pendingcb++;
	    ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
	  }
	
	  return ret;
	};
	
	Writable.prototype.cork = function () {
	  var state = this._writableState;
	
	  state.corked++;
	};
	
	Writable.prototype.uncork = function () {
	  var state = this._writableState;
	
	  if (state.corked) {
	    state.corked--;
	
	    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
	  }
	};
	
	Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
	  // node::ParseEncoding() requires lower case.
	  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
	  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
	  this._writableState.defaultEncoding = encoding;
	  return this;
	};
	
	function decodeChunk(state, chunk, encoding) {
	  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
	    chunk = Buffer.from(chunk, encoding);
	  }
	  return chunk;
	}
	
	// if we're already writing something, then just put this
	// in the queue, and wait our turn.  Otherwise, call _write
	// If we return false, then we need a drain event, so set that flag.
	function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
	  if (!isBuf) {
	    var newChunk = decodeChunk(state, chunk, encoding);
	    if (chunk !== newChunk) {
	      isBuf = true;
	      encoding = 'buffer';
	      chunk = newChunk;
	    }
	  }
	  var len = state.objectMode ? 1 : chunk.length;
	
	  state.length += len;
	
	  var ret = state.length < state.highWaterMark;
	  // we must ensure that previous needDrain will not be reset to false.
	  if (!ret) state.needDrain = true;
	
	  if (state.writing || state.corked) {
	    var last = state.lastBufferedRequest;
	    state.lastBufferedRequest = {
	      chunk: chunk,
	      encoding: encoding,
	      isBuf: isBuf,
	      callback: cb,
	      next: null
	    };
	    if (last) {
	      last.next = state.lastBufferedRequest;
	    } else {
	      state.bufferedRequest = state.lastBufferedRequest;
	    }
	    state.bufferedRequestCount += 1;
	  } else {
	    doWrite(stream, state, false, len, chunk, encoding, cb);
	  }
	
	  return ret;
	}
	
	function doWrite(stream, state, writev, len, chunk, encoding, cb) {
	  state.writelen = len;
	  state.writecb = cb;
	  state.writing = true;
	  state.sync = true;
	  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
	  state.sync = false;
	}
	
	function onwriteError(stream, state, sync, er, cb) {
	  --state.pendingcb;
	
	  if (sync) {
	    // defer the callback if we are being called synchronously
	    // to avoid piling up things on the stack
	    processNextTick(cb, er);
	    // this can emit finish, and it will always happen
	    // after error
	    processNextTick(finishMaybe, stream, state);
	    stream._writableState.errorEmitted = true;
	    stream.emit('error', er);
	  } else {
	    // the caller expect this to happen before if
	    // it is async
	    cb(er);
	    stream._writableState.errorEmitted = true;
	    stream.emit('error', er);
	    // this can emit finish, but finish must
	    // always follow error
	    finishMaybe(stream, state);
	  }
	}
	
	function onwriteStateUpdate(state) {
	  state.writing = false;
	  state.writecb = null;
	  state.length -= state.writelen;
	  state.writelen = 0;
	}
	
	function onwrite(stream, er) {
	  var state = stream._writableState;
	  var sync = state.sync;
	  var cb = state.writecb;
	
	  onwriteStateUpdate(state);
	
	  if (er) onwriteError(stream, state, sync, er, cb);else {
	    // Check if we're actually ready to finish, but don't emit yet
	    var finished = needFinish(state);
	
	    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
	      clearBuffer(stream, state);
	    }
	
	    if (sync) {
	      /*<replacement>*/
	      asyncWrite(afterWrite, stream, state, finished, cb);
	      /*</replacement>*/
	    } else {
	      afterWrite(stream, state, finished, cb);
	    }
	  }
	}
	
	function afterWrite(stream, state, finished, cb) {
	  if (!finished) onwriteDrain(stream, state);
	  state.pendingcb--;
	  cb();
	  finishMaybe(stream, state);
	}
	
	// Must force callback to be called on nextTick, so that we don't
	// emit 'drain' before the write() consumer gets the 'false' return
	// value, and has a chance to attach a 'drain' listener.
	function onwriteDrain(stream, state) {
	  if (state.length === 0 && state.needDrain) {
	    state.needDrain = false;
	    stream.emit('drain');
	  }
	}
	
	// if there's something in the buffer waiting, then process it
	function clearBuffer(stream, state) {
	  state.bufferProcessing = true;
	  var entry = state.bufferedRequest;
	
	  if (stream._writev && entry && entry.next) {
	    // Fast case, write everything using _writev()
	    var l = state.bufferedRequestCount;
	    var buffer = new Array(l);
	    var holder = state.corkedRequestsFree;
	    holder.entry = entry;
	
	    var count = 0;
	    var allBuffers = true;
	    while (entry) {
	      buffer[count] = entry;
	      if (!entry.isBuf) allBuffers = false;
	      entry = entry.next;
	      count += 1;
	    }
	    buffer.allBuffers = allBuffers;
	
	    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
	
	    // doWrite is almost always async, defer these to save a bit of time
	    // as the hot path ends with doWrite
	    state.pendingcb++;
	    state.lastBufferedRequest = null;
	    if (holder.next) {
	      state.corkedRequestsFree = holder.next;
	      holder.next = null;
	    } else {
	      state.corkedRequestsFree = new CorkedRequest(state);
	    }
	  } else {
	    // Slow case, write chunks one-by-one
	    while (entry) {
	      var chunk = entry.chunk;
	      var encoding = entry.encoding;
	      var cb = entry.callback;
	      var len = state.objectMode ? 1 : chunk.length;
	
	      doWrite(stream, state, false, len, chunk, encoding, cb);
	      entry = entry.next;
	      // if we didn't call the onwrite immediately, then
	      // it means that we need to wait until it does.
	      // also, that means that the chunk and cb are currently
	      // being processed, so move the buffer counter past them.
	      if (state.writing) {
	        break;
	      }
	    }
	
	    if (entry === null) state.lastBufferedRequest = null;
	  }
	
	  state.bufferedRequestCount = 0;
	  state.bufferedRequest = entry;
	  state.bufferProcessing = false;
	}
	
	Writable.prototype._write = function (chunk, encoding, cb) {
	  cb(new Error('_write() is not implemented'));
	};
	
	Writable.prototype._writev = null;
	
	Writable.prototype.end = function (chunk, encoding, cb) {
	  var state = this._writableState;
	
	  if (typeof chunk === 'function') {
	    cb = chunk;
	    chunk = null;
	    encoding = null;
	  } else if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }
	
	  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
	
	  // .end() fully uncorks
	  if (state.corked) {
	    state.corked = 1;
	    this.uncork();
	  }
	
	  // ignore unnecessary end() calls.
	  if (!state.ending && !state.finished) endWritable(this, state, cb);
	};
	
	function needFinish(state) {
	  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
	}
	function callFinal(stream, state) {
	  stream._final(function (err) {
	    state.pendingcb--;
	    if (err) {
	      stream.emit('error', err);
	    }
	    state.prefinished = true;
	    stream.emit('prefinish');
	    finishMaybe(stream, state);
	  });
	}
	function prefinish(stream, state) {
	  if (!state.prefinished && !state.finalCalled) {
	    if (typeof stream._final === 'function') {
	      state.pendingcb++;
	      state.finalCalled = true;
	      processNextTick(callFinal, stream, state);
	    } else {
	      state.prefinished = true;
	      stream.emit('prefinish');
	    }
	  }
	}
	
	function finishMaybe(stream, state) {
	  var need = needFinish(state);
	  if (need) {
	    prefinish(stream, state);
	    if (state.pendingcb === 0) {
	      state.finished = true;
	      stream.emit('finish');
	    }
	  }
	  return need;
	}
	
	function endWritable(stream, state, cb) {
	  state.ending = true;
	  finishMaybe(stream, state);
	  if (cb) {
	    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
	  }
	  state.ended = true;
	  stream.writable = false;
	}
	
	function onCorkedFinish(corkReq, state, err) {
	  var entry = corkReq.entry;
	  corkReq.entry = null;
	  while (entry) {
	    var cb = entry.callback;
	    state.pendingcb--;
	    cb(err);
	    entry = entry.next;
	  }
	  if (state.corkedRequestsFree) {
	    state.corkedRequestsFree.next = corkReq;
	  } else {
	    state.corkedRequestsFree = corkReq;
	  }
	}
	
	Object.defineProperty(Writable.prototype, 'destroyed', {
	  get: function () {
	    if (this._writableState === undefined) {
	      return false;
	    }
	    return this._writableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._writableState) {
	      return;
	    }
	
	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._writableState.destroyed = value;
	  }
	});
	
	Writable.prototype.destroy = destroyImpl.destroy;
	Writable.prototype._undestroy = destroyImpl.undestroy;
	Writable.prototype._destroy = function (err, cb) {
	  this.end();
	  cb(err);
	};
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(22), __webpack_require__(51).setImmediate, (function() { return this; }())))

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

	var apply = Function.prototype.apply;
	
	// DOM APIs, for completeness
	
	exports.setTimeout = function() {
	  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
	};
	exports.setInterval = function() {
	  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
	};
	exports.clearTimeout =
	exports.clearInterval = function(timeout) {
	  if (timeout) {
	    timeout.close();
	  }
	};
	
	function Timeout(id, clearFn) {
	  this._id = id;
	  this._clearFn = clearFn;
	}
	Timeout.prototype.unref = Timeout.prototype.ref = function() {};
	Timeout.prototype.close = function() {
	  this._clearFn.call(window, this._id);
	};
	
	// Does not start the time, just sets up the members needed.
	exports.enroll = function(item, msecs) {
	  clearTimeout(item._idleTimeoutId);
	  item._idleTimeout = msecs;
	};
	
	exports.unenroll = function(item) {
	  clearTimeout(item._idleTimeoutId);
	  item._idleTimeout = -1;
	};
	
	exports._unrefActive = exports.active = function(item) {
	  clearTimeout(item._idleTimeoutId);
	
	  var msecs = item._idleTimeout;
	  if (msecs >= 0) {
	    item._idleTimeoutId = setTimeout(function onTimeout() {
	      if (item._onTimeout)
	        item._onTimeout();
	    }, msecs);
	  }
	};
	
	// setimmediate attaches itself to the global object
	__webpack_require__(52);
	exports.setImmediate = setImmediate;
	exports.clearImmediate = clearImmediate;


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

	/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
	    "use strict";
	
	    if (global.setImmediate) {
	        return;
	    }
	
	    var nextHandle = 1; // Spec says greater than zero
	    var tasksByHandle = {};
	    var currentlyRunningATask = false;
	    var doc = global.document;
	    var registerImmediate;
	
	    function setImmediate(callback) {
	      // Callback can either be a function or a string
	      if (typeof callback !== "function") {
	        callback = new Function("" + callback);
	      }
	      // Copy function arguments
	      var args = new Array(arguments.length - 1);
	      for (var i = 0; i < args.length; i++) {
	          args[i] = arguments[i + 1];
	      }
	      // Store and register the task
	      var task = { callback: callback, args: args };
	      tasksByHandle[nextHandle] = task;
	      registerImmediate(nextHandle);
	      return nextHandle++;
	    }
	
	    function clearImmediate(handle) {
	        delete tasksByHandle[handle];
	    }
	
	    function run(task) {
	        var callback = task.callback;
	        var args = task.args;
	        switch (args.length) {
	        case 0:
	            callback();
	            break;
	        case 1:
	            callback(args[0]);
	            break;
	        case 2:
	            callback(args[0], args[1]);
	            break;
	        case 3:
	            callback(args[0], args[1], args[2]);
	            break;
	        default:
	            callback.apply(undefined, args);
	            break;
	        }
	    }
	
	    function runIfPresent(handle) {
	        // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
	        // So if we're currently running a task, we'll need to delay this invocation.
	        if (currentlyRunningATask) {
	            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
	            // "too much recursion" error.
	            setTimeout(runIfPresent, 0, handle);
	        } else {
	            var task = tasksByHandle[handle];
	            if (task) {
	                currentlyRunningATask = true;
	                try {
	                    run(task);
	                } finally {
	                    clearImmediate(handle);
	                    currentlyRunningATask = false;
	                }
	            }
	        }
	    }
	
	    function installNextTickImplementation() {
	        registerImmediate = function(handle) {
	            process.nextTick(function () { runIfPresent(handle); });
	        };
	    }
	
	    function canUsePostMessage() {
	        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
	        // where `global.postMessage` means something completely different and can't be used for this purpose.
	        if (global.postMessage && !global.importScripts) {
	            var postMessageIsAsynchronous = true;
	            var oldOnMessage = global.onmessage;
	            global.onmessage = function() {
	                postMessageIsAsynchronous = false;
	            };
	            global.postMessage("", "*");
	            global.onmessage = oldOnMessage;
	            return postMessageIsAsynchronous;
	        }
	    }
	
	    function installPostMessageImplementation() {
	        // Installs an event handler on `global` for the `message` event: see
	        // * https://developer.mozilla.org/en/DOM/window.postMessage
	        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
	
	        var messagePrefix = "setImmediate$" + Math.random() + "$";
	        var onGlobalMessage = function(event) {
	            if (event.source === global &&
	                typeof event.data === "string" &&
	                event.data.indexOf(messagePrefix) === 0) {
	                runIfPresent(+event.data.slice(messagePrefix.length));
	            }
	        };
	
	        if (global.addEventListener) {
	            global.addEventListener("message", onGlobalMessage, false);
	        } else {
	            global.attachEvent("onmessage", onGlobalMessage);
	        }
	
	        registerImmediate = function(handle) {
	            global.postMessage(messagePrefix + handle, "*");
	        };
	    }
	
	    function installMessageChannelImplementation() {
	        var channel = new MessageChannel();
	        channel.port1.onmessage = function(event) {
	            var handle = event.data;
	            runIfPresent(handle);
	        };
	
	        registerImmediate = function(handle) {
	            channel.port2.postMessage(handle);
	        };
	    }
	
	    function installReadyStateChangeImplementation() {
	        var html = doc.documentElement;
	        registerImmediate = function(handle) {
	            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
	            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
	            var script = doc.createElement("script");
	            script.onreadystatechange = function () {
	                runIfPresent(handle);
	                script.onreadystatechange = null;
	                html.removeChild(script);
	                script = null;
	            };
	            html.appendChild(script);
	        };
	    }
	
	    function installSetTimeoutImplementation() {
	        registerImmediate = function(handle) {
	            setTimeout(runIfPresent, 0, handle);
	        };
	    }
	
	    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
	    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
	    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
	
	    // Don't get fooled by e.g. browserify environments.
	    if ({}.toString.call(global.process) === "[object process]") {
	        // For Node.js before 0.9
	        installNextTickImplementation();
	
	    } else if (canUsePostMessage()) {
	        // For non-IE10 modern browsers
	        installPostMessageImplementation();
	
	    } else if (global.MessageChannel) {
	        // For web workers, where supported
	        installMessageChannelImplementation();
	
	    } else if (doc && "onreadystatechange" in doc.createElement("script")) {
	        // For IE 6–8
	        installReadyStateChangeImplementation();
	
	    } else {
	        // For older browsers
	        installSetTimeoutImplementation();
	    }
	
	    attachTo.setImmediate = setImmediate;
	    attachTo.clearImmediate = clearImmediate;
	}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(22)))

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

	/* WEBPACK VAR INJECTION */(function(global) {
	/**
	 * Module exports.
	 */
	
	module.exports = deprecate;
	
	/**
	 * Mark that a method should not be used.
	 * Returns a modified function which warns once by default.
	 *
	 * If `localStorage.noDeprecation = true` is set, then it is a no-op.
	 *
	 * If `localStorage.throwDeprecation = true` is set, then deprecated functions
	 * will throw an Error when invoked.
	 *
	 * If `localStorage.traceDeprecation = true` is set, then deprecated functions
	 * will invoke `console.trace()` instead of `console.error()`.
	 *
	 * @param {Function} fn - the function to deprecate
	 * @param {String} msg - the string to print to the console when `fn` is invoked
	 * @returns {Function} a new "deprecated" version of `fn`
	 * @api public
	 */
	
	function deprecate (fn, msg) {
	  if (config('noDeprecation')) {
	    return fn;
	  }
	
	  var warned = false;
	  function deprecated() {
	    if (!warned) {
	      if (config('throwDeprecation')) {
	        throw new Error(msg);
	      } else if (config('traceDeprecation')) {
	        console.trace(msg);
	      } else {
	        console.warn(msg);
	      }
	      warned = true;
	    }
	    return fn.apply(this, arguments);
	  }
	
	  return deprecated;
	}
	
	/**
	 * Checks `localStorage` for boolean values for the given `name`.
	 *
	 * @param {String} name
	 * @returns {Boolean}
	 * @api private
	 */
	
	function config (name) {
	  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
	  try {
	    if (!global.localStorage) return false;
	  } catch (_) {
	    return false;
	  }
	  var val = global.localStorage[name];
	  if (null == val) return false;
	  return String(val).toLowerCase() === 'true';
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

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

	'use strict';
	
	var Buffer = __webpack_require__(44).Buffer;
	
	var isEncoding = Buffer.isEncoding || function (encoding) {
	  encoding = '' + encoding;
	  switch (encoding && encoding.toLowerCase()) {
	    case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
	      return true;
	    default:
	      return false;
	  }
	};
	
	function _normalizeEncoding(enc) {
	  if (!enc) return 'utf8';
	  var retried;
	  while (true) {
	    switch (enc) {
	      case 'utf8':
	      case 'utf-8':
	        return 'utf8';
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return 'utf16le';
	      case 'latin1':
	      case 'binary':
	        return 'latin1';
	      case 'base64':
	      case 'ascii':
	      case 'hex':
	        return enc;
	      default:
	        if (retried) return; // undefined
	        enc = ('' + enc).toLowerCase();
	        retried = true;
	    }
	  }
	};
	
	// Do not cache `Buffer.isEncoding` when checking encoding names as some
	// modules monkey-patch it to support additional encodings
	function normalizeEncoding(enc) {
	  var nenc = _normalizeEncoding(enc);
	  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
	  return nenc || enc;
	}
	
	// StringDecoder provides an interface for efficiently splitting a series of
	// buffers into a series of JS strings without breaking apart multi-byte
	// characters.
	exports.StringDecoder = StringDecoder;
	function StringDecoder(encoding) {
	  this.encoding = normalizeEncoding(encoding);
	  var nb;
	  switch (this.encoding) {
	    case 'utf16le':
	      this.text = utf16Text;
	      this.end = utf16End;
	      nb = 4;
	      break;
	    case 'utf8':
	      this.fillLast = utf8FillLast;
	      nb = 4;
	      break;
	    case 'base64':
	      this.text = base64Text;
	      this.end = base64End;
	      nb = 3;
	      break;
	    default:
	      this.write = simpleWrite;
	      this.end = simpleEnd;
	      return;
	  }
	  this.lastNeed = 0;
	  this.lastTotal = 0;
	  this.lastChar = Buffer.allocUnsafe(nb);
	}
	
	StringDecoder.prototype.write = function (buf) {
	  if (buf.length === 0) return '';
	  var r;
	  var i;
	  if (this.lastNeed) {
	    r = this.fillLast(buf);
	    if (r === undefined) return '';
	    i = this.lastNeed;
	    this.lastNeed = 0;
	  } else {
	    i = 0;
	  }
	  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
	  return r || '';
	};
	
	StringDecoder.prototype.end = utf8End;
	
	// Returns only complete characters in a Buffer
	StringDecoder.prototype.text = utf8Text;
	
	// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
	StringDecoder.prototype.fillLast = function (buf) {
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
	  this.lastNeed -= buf.length;
	};
	
	// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
	// continuation byte.
	function utf8CheckByte(byte) {
	  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
	  return -1;
	}
	
	// Checks at most 3 bytes at the end of a Buffer in order to detect an
	// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
	// needed to complete the UTF-8 character (if applicable) are returned.
	function utf8CheckIncomplete(self, buf, i) {
	  var j = buf.length - 1;
	  if (j < i) return 0;
	  var nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 1;
	    return nb;
	  }
	  if (--j < i) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 2;
	    return nb;
	  }
	  if (--j < i) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) {
	      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
	    }
	    return nb;
	  }
	  return 0;
	}
	
	// Validates as many continuation bytes for a multi-byte UTF-8 character as
	// needed or are available. If we see a non-continuation byte where we expect
	// one, we "replace" the validated continuation bytes we've seen so far with
	// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding
	// behavior. The continuation byte check is included three times in the case
	// where all of the continuation bytes for a character exist in the same buffer.
	// It is also done this way as a slight performance increase instead of using a
	// loop.
	function utf8CheckExtraBytes(self, buf, p) {
	  if ((buf[0] & 0xC0) !== 0x80) {
	    self.lastNeed = 0;
	    return '\ufffd'.repeat(p);
	  }
	  if (self.lastNeed > 1 && buf.length > 1) {
	    if ((buf[1] & 0xC0) !== 0x80) {
	      self.lastNeed = 1;
	      return '\ufffd'.repeat(p + 1);
	    }
	    if (self.lastNeed > 2 && buf.length > 2) {
	      if ((buf[2] & 0xC0) !== 0x80) {
	        self.lastNeed = 2;
	        return '\ufffd'.repeat(p + 2);
	      }
	    }
	  }
	}
	
	// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
	function utf8FillLast(buf) {
	  var p = this.lastTotal - this.lastNeed;
	  var r = utf8CheckExtraBytes(this, buf, p);
	  if (r !== undefined) return r;
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, p, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, p, 0, buf.length);
	  this.lastNeed -= buf.length;
	}
	
	// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
	// partial character, the character's bytes are buffered until the required
	// number of bytes are available.
	function utf8Text(buf, i) {
	  var total = utf8CheckIncomplete(this, buf, i);
	  if (!this.lastNeed) return buf.toString('utf8', i);
	  this.lastTotal = total;
	  var end = buf.length - (total - this.lastNeed);
	  buf.copy(this.lastChar, 0, end);
	  return buf.toString('utf8', i, end);
	}
	
	// For UTF-8, a replacement character for each buffered byte of a (partial)
	// character needs to be added to the output.
	function utf8End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed);
	  return r;
	}
	
	// UTF-16LE typically needs two bytes per character, but even if we have an even
	// number of bytes available, we need to check if we end on a leading/high
	// surrogate. In that case, we need to wait for the next two bytes in order to
	// decode the last character properly.
	function utf16Text(buf, i) {
	  if ((buf.length - i) % 2 === 0) {
	    var r = buf.toString('utf16le', i);
	    if (r) {
	      var c = r.charCodeAt(r.length - 1);
	      if (c >= 0xD800 && c <= 0xDBFF) {
	        this.lastNeed = 2;
	        this.lastTotal = 4;
	        this.lastChar[0] = buf[buf.length - 2];
	        this.lastChar[1] = buf[buf.length - 1];
	        return r.slice(0, -1);
	      }
	    }
	    return r;
	  }
	  this.lastNeed = 1;
	  this.lastTotal = 2;
	  this.lastChar[0] = buf[buf.length - 1];
	  return buf.toString('utf16le', i, buf.length - 1);
	}
	
	// For UTF-16LE we do not explicitly append special replacement characters if we
	// end on a partial character, we simply let v8 handle that.
	function utf16End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) {
	    var end = this.lastTotal - this.lastNeed;
	    return r + this.lastChar.toString('utf16le', 0, end);
	  }
	  return r;
	}
	
	function base64Text(buf, i) {
	  var n = (buf.length - i) % 3;
	  if (n === 0) return buf.toString('base64', i);
	  this.lastNeed = 3 - n;
	  this.lastTotal = 3;
	  if (n === 1) {
	    this.lastChar[0] = buf[buf.length - 1];
	  } else {
	    this.lastChar[0] = buf[buf.length - 2];
	    this.lastChar[1] = buf[buf.length - 1];
	  }
	  return buf.toString('base64', i, buf.length - n);
	}
	
	function base64End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
	  return r;
	}
	
	// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
	function simpleWrite(buf) {
	  return buf.toString(this.encoding);
	}
	
	function simpleEnd(buf) {
	  return buf && buf.length ? this.write(buf) : '';
	}

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

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// a transform stream is a readable/writable stream where you do
	// something with the data.  Sometimes it's called a "filter",
	// but that's not a great name for it, since that implies a thing where
	// some bits pass through, and others are simply ignored.  (That would
	// be a valid example of a transform, of course.)
	//
	// While the output is causally related to the input, it's not a
	// necessarily symmetric or synchronous transformation.  For example,
	// a zlib stream might take multiple plain-text writes(), and then
	// emit a single compressed chunk some time in the future.
	//
	// Here's how this works:
	//
	// The Transform stream has all the aspects of the readable and writable
	// stream classes.  When you write(chunk), that calls _write(chunk,cb)
	// internally, and returns false if there's a lot of pending writes
	// buffered up.  When you call read(), that calls _read(n) until
	// there's enough pending readable data buffered up.
	//
	// In a transform stream, the written data is placed in a buffer.  When
	// _read(n) is called, it transforms the queued up data, calling the
	// buffered _write cb's as it consumes chunks.  If consuming a single
	// written chunk would result in multiple output chunks, then the first
	// outputted bit calls the readcb, and subsequent chunks just go into
	// the read buffer, and will cause it to emit 'readable' if necessary.
	//
	// This way, back-pressure is actually determined by the reading side,
	// since _read has to be called to start processing a new chunk.  However,
	// a pathological inflate type of transform can cause excessive buffering
	// here.  For example, imagine a stream where every byte of input is
	// interpreted as an integer from 0-255, and then results in that many
	// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
	// 1kb of data being output.  In this case, you could write a very small
	// amount of input, and end up with a very large amount of output.  In
	// such a pathological inflating mechanism, there'd be no way to tell
	// the system to stop doing the transform.  A single 4MB write could
	// cause the system to run out of memory.
	//
	// However, even in such a pathological case, only a single written chunk
	// would be consumed, and then the rest would wait (un-transformed) until
	// the results of the previous transformed chunk were consumed.
	
	'use strict';
	
	module.exports = Transform;
	
	var Duplex = __webpack_require__(49);
	
	/*<replacement>*/
	var util = __webpack_require__(45);
	util.inherits = __webpack_require__(39);
	/*</replacement>*/
	
	util.inherits(Transform, Duplex);
	
	function TransformState(stream) {
	  this.afterTransform = function (er, data) {
	    return afterTransform(stream, er, data);
	  };
	
	  this.needTransform = false;
	  this.transforming = false;
	  this.writecb = null;
	  this.writechunk = null;
	  this.writeencoding = null;
	}
	
	function afterTransform(stream, er, data) {
	  var ts = stream._transformState;
	  ts.transforming = false;
	
	  var cb = ts.writecb;
	
	  if (!cb) {
	    return stream.emit('error', new Error('write callback called multiple times'));
	  }
	
	  ts.writechunk = null;
	  ts.writecb = null;
	
	  if (data !== null && data !== undefined) stream.push(data);
	
	  cb(er);
	
	  var rs = stream._readableState;
	  rs.reading = false;
	  if (rs.needReadable || rs.length < rs.highWaterMark) {
	    stream._read(rs.highWaterMark);
	  }
	}
	
	function Transform(options) {
	  if (!(this instanceof Transform)) return new Transform(options);
	
	  Duplex.call(this, options);
	
	  this._transformState = new TransformState(this);
	
	  var stream = this;
	
	  // start out asking for a readable event once data is transformed.
	  this._readableState.needReadable = true;
	
	  // we have implemented the _read method, and done the other things
	  // that Readable wants before the first _read call, so unset the
	  // sync guard flag.
	  this._readableState.sync = false;
	
	  if (options) {
	    if (typeof options.transform === 'function') this._transform = options.transform;
	
	    if (typeof options.flush === 'function') this._flush = options.flush;
	  }
	
	  // When the writable side finishes, then flush out anything remaining.
	  this.once('prefinish', function () {
	    if (typeof this._flush === 'function') this._flush(function (er, data) {
	      done(stream, er, data);
	    });else done(stream);
	  });
	}
	
	Transform.prototype.push = function (chunk, encoding) {
	  this._transformState.needTransform = false;
	  return Duplex.prototype.push.call(this, chunk, encoding);
	};
	
	// This is the part where you do stuff!
	// override this function in implementation classes.
	// 'chunk' is an input chunk.
	//
	// Call `push(newChunk)` to pass along transformed output
	// to the readable side.  You may call 'push' zero or more times.
	//
	// Call `cb(err)` when you are done with this chunk.  If you pass
	// an error, then that'll put the hurt on the whole operation.  If you
	// never call cb(), then you'll never get another chunk.
	Transform.prototype._transform = function (chunk, encoding, cb) {
	  throw new Error('_transform() is not implemented');
	};
	
	Transform.prototype._write = function (chunk, encoding, cb) {
	  var ts = this._transformState;
	  ts.writecb = cb;
	  ts.writechunk = chunk;
	  ts.writeencoding = encoding;
	  if (!ts.transforming) {
	    var rs = this._readableState;
	    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
	  }
	};
	
	// Doesn't matter what the args are here.
	// _transform does all the work.
	// That we got here means that the readable side wants more data.
	Transform.prototype._read = function (n) {
	  var ts = this._transformState;
	
	  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
	    ts.transforming = true;
	    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
	  } else {
	    // mark that we need a transform, so that any data that comes in
	    // will get processed, now that we've asked for it.
	    ts.needTransform = true;
	  }
	};
	
	Transform.prototype._destroy = function (err, cb) {
	  var _this = this;
	
	  Duplex.prototype._destroy.call(this, err, function (err2) {
	    cb(err2);
	    _this.emit('close');
	  });
	};
	
	function done(stream, er, data) {
	  if (er) return stream.emit('error', er);
	
	  if (data !== null && data !== undefined) stream.push(data);
	
	  // if there's nothing in the write buffer, then that means
	  // that nothing more will ever be provided
	  var ws = stream._writableState;
	  var ts = stream._transformState;
	
	  if (ws.length) throw new Error('Calling transform done when ws.length != 0');
	
	  if (ts.transforming) throw new Error('Calling transform done when still transforming');
	
	  return stream.push(null);
	}

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

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// a passthrough stream.
	// basically just the most minimal sort of Transform stream.
	// Every written chunk gets output as-is.
	
	'use strict';
	
	module.exports = PassThrough;
	
	var Transform = __webpack_require__(55);
	
	/*<replacement>*/
	var util = __webpack_require__(45);
	util.inherits = __webpack_require__(39);
	/*</replacement>*/
	
	util.inherits(PassThrough, Transform);
	
	function PassThrough(options) {
	  if (!(this instanceof PassThrough)) return new PassThrough(options);
	
	  Transform.call(this, options);
	}
	
	PassThrough.prototype._transform = function (chunk, encoding, cb) {
	  cb(null, chunk);
	};

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

	module.exports = __webpack_require__(50);


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

	module.exports = __webpack_require__(49);


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

	module.exports = __webpack_require__(40).Transform


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

	module.exports = __webpack_require__(40).PassThrough


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

	exports['aes-128-ecb'] = {
	  cipher: 'AES',
	  key: 128,
	  iv: 0,
	  mode: 'ECB',
	  type: 'block'
	};
	exports['aes-192-ecb'] = {
	  cipher: 'AES',
	  key: 192,
	  iv: 0,
	  mode: 'ECB',
	  type: 'block'
	};
	exports['aes-256-ecb'] = {
	  cipher: 'AES',
	  key: 256,
	  iv: 0,
	  mode: 'ECB',
	  type: 'block'
	};
	exports['aes-128-cbc'] = {
	  cipher: 'AES',
	  key: 128,
	  iv: 16,
	  mode: 'CBC',
	  type: 'block'
	};
	exports['aes-192-cbc'] = {
	  cipher: 'AES',
	  key: 192,
	  iv: 16,
	  mode: 'CBC',
	  type: 'block'
	};
	exports['aes-256-cbc'] = {
	  cipher: 'AES',
	  key: 256,
	  iv: 16,
	  mode: 'CBC',
	  type: 'block'
	};
	exports['aes128'] = exports['aes-128-cbc'];
	exports['aes192'] = exports['aes-192-cbc'];
	exports['aes256'] = exports['aes-256-cbc'];
	exports['aes-128-cfb'] = {
	  cipher: 'AES',
	  key: 128,
	  iv: 16,
	  mode: 'CFB',
	  type: 'stream'
	};
	exports['aes-192-cfb'] = {
	  cipher: 'AES',
	  key: 192,
	  iv: 16,
	  mode: 'CFB',
	  type: 'stream'
	};
	exports['aes-256-cfb'] = {
	  cipher: 'AES',
	  key: 256,
	  iv: 16,
	  mode: 'CFB',
	  type: 'stream'
	};
	exports['aes-128-ofb'] = {
	  cipher: 'AES',
	  key: 128,
	  iv: 16,
	  mode: 'OFB',
	  type: 'stream'
	};
	exports['aes-192-ofb'] = {
	  cipher: 'AES',
	  key: 192,
	  iv: 16,
	  mode: 'OFB',
	  type: 'stream'
	};
	exports['aes-256-ofb'] = {
	  cipher: 'AES',
	  key: 256,
	  iv: 16,
	  mode: 'OFB',
	  type: 'stream'
	};
	exports['aes-128-ctr'] = {
	  cipher: 'AES',
	  key: 128,
	  iv: 16,
	  mode: 'CTR',
	  type: 'stream'
	};
	exports['aes-192-ctr'] = {
	  cipher: 'AES',
	  key: 192,
	  iv: 16,
	  mode: 'CTR',
	  type: 'stream'
	};
	exports['aes-256-ctr'] = {
	  cipher: 'AES',
	  key: 256,
	  iv: 16,
	  mode: 'CTR',
	  type: 'stream'
	};

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {
	module.exports = function (crypto, password, keyLen, ivLen) {
	  keyLen = keyLen/8;
	  ivLen = ivLen || 0;
	  var ki = 0;
	  var ii = 0;
	  var key = new Buffer(keyLen);
	  var iv = new Buffer(ivLen);
	  var addmd = 0;
	  var md, md_buf;
	  var i;
	  while (true) {
	    md = crypto.createHash('md5');
	    if(addmd++ > 0) {
	       md.update(md_buf);
	    }
	    md.update(password);
	    md_buf = md.digest();
	    i = 0;
	    if(keyLen > 0) {
	      while(true) {
	        if(keyLen === 0) {
	          break;
	        }
	        if(i === md_buf.length) {
	          break;
	        }
	        key[ki++] = md_buf[i];
	        keyLen--;
	        i++;
	       }
	    }
	    if(ivLen > 0 && i !== md_buf.length) {
	      while(true) {
	        if(ivLen === 0) {
	          break;
	        }
	        if(i === md_buf.length) {
	          break;
	        }
	       iv[ii++] = md_buf[i];
	       ivLen--;
	       i++;
	     }
	   }
	   if(keyLen === 0 && ivLen === 0) {
	      break;
	    }
	  }
	  for(i=0;i<md_buf.length;i++) {
	    md_buf[i] = 0;
	  }
	  return {
	    key: key,
	    iv: iv
	  };
	};
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var aes = __webpack_require__(35);
	var Transform = __webpack_require__(36);
	var inherits = __webpack_require__(39);
	
	inherits(StreamCipher, Transform);
	module.exports = StreamCipher;
	function StreamCipher(mode, key, iv, decrypt) {
	  if (!(this instanceof StreamCipher)) {
	    return new StreamCipher(mode, key, iv);
	  }
	  Transform.call(this);
	  this._cipher = new aes.AES(key);
	  this._prev = new Buffer(iv.length);
	  this._cache = new Buffer('');
	  this._secCache = new Buffer('');
	  this._decrypt = decrypt;
	  iv.copy(this._prev);
	  this._mode = mode;
	}
	StreamCipher.prototype._transform = function (chunk, _, next) {
	  next(null, this._mode.encrypt(this, chunk, this._decrypt));
	};
	StreamCipher.prototype._flush = function (next) {
	  this._cipher.scrub();
	  next();
	};
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	exports.encrypt = function (self, block) {
	  return self._cipher.encryptBlock(block);
	};
	exports.decrypt = function (self, block) {
	  return self._cipher.decryptBlock(block);
	};

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

	var xor = __webpack_require__(66);
	exports.encrypt = function (self, block) {
	  var data = xor(block, self._prev);
	  self._prev = self._cipher.encryptBlock(data);
	  return self._prev;
	};
	exports.decrypt = function (self, block) {
	  var pad = self._prev;
	  self._prev = block;
	  var out = self._cipher.decryptBlock(block);
	  return xor(out, pad);
	};

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {module.exports = xor;
	function xor(a, b) {
	  var len = Math.min(a.length, b.length);
	  var out = new Buffer(len);
	  var i = -1;
	  while (++i < len) {
	    out.writeUInt8(a[i] ^ b[i], i);
	  }
	  return out;
	}
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var xor = __webpack_require__(66);
	exports.encrypt = function (self, data, decrypt) {
	  var out = new Buffer('');
	  var len;
	  while (data.length) {
	    if (self._cache.length === 0) {
	      self._cache = self._cipher.encryptBlock(self._prev);
	      self._prev = new Buffer('');
	    }
	    if (self._cache.length <= data.length) {
	      len = self._cache.length;
	      out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)]);
	      data = data.slice(len);
	    } else {
	      out = Buffer.concat([out, encryptStart(self, data, decrypt)]);
	      break;
	    }
	  }
	  return out;
	};
	function encryptStart(self, data, decrypt) {
	  var len = data.length;
	  var out = xor(data, self._cache);
	  self._cache = self._cache.slice(len);
	  self._prev = Buffer.concat([self._prev, decrypt?data:out]);
	  return out;
	}
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var xor = __webpack_require__(66);
	function getBlock(self) {
	  self._prev = self._cipher.encryptBlock(self._prev);
	  return self._prev;
	}
	exports.encrypt = function (self, chunk) {
	  while (self._cache.length < chunk.length) {
	    self._cache = Buffer.concat([self._cache, getBlock(self)]);
	  }
	  var pad = self._cache.slice(0, chunk.length);
	  self._cache = self._cache.slice(chunk.length);
	  return xor(chunk, pad);
	};
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var xor = __webpack_require__(66);
	function getBlock(self) {
	  var out = self._cipher.encryptBlock(self._prev);
	  incr32(self._prev);
	  return out;
	}
	exports.encrypt = function (self, chunk) {
	  while (self._cache.length < chunk.length) {
	    self._cache = Buffer.concat([self._cache, getBlock(self)]);
	  }
	  var pad = self._cache.slice(0, chunk.length);
	  self._cache = self._cache.slice(chunk.length);
	  return xor(chunk, pad);
	};
	function incr32(iv) {
	  var len = iv.length;
	  var item;
	  while (len--) {
	    item = iv.readUInt8(len);
	    if (item === 255) {
	      iv.writeUInt8(0, len);
	    } else {
	      item++;
	      iv.writeUInt8(item, len);
	      break;
	    }
	  }
	}
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	/* WEBPACK VAR INJECTION */(function(Buffer) {var aes = __webpack_require__(35);
	var Transform = __webpack_require__(36);
	var inherits = __webpack_require__(39);
	var modes = __webpack_require__(61);
	var StreamCipher = __webpack_require__(63);
	var ebtk = __webpack_require__(62);
	
	inherits(Decipher, Transform);
	function Decipher(mode, key, iv) {
	  if (!(this instanceof Decipher)) {
	    return new Decipher(mode, key, iv);
	  }
	  Transform.call(this);
	  this._cache = new Splitter();
	  this._last = void 0;
	  this._cipher = new aes.AES(key);
	  this._prev = new Buffer(iv.length);
	  iv.copy(this._prev);
	  this._mode = mode;
	}
	Decipher.prototype._transform = function (data, _, next) {
	  this._cache.add(data);
	  var chunk;
	  var thing;
	  while ((chunk = this._cache.get())) {
	    thing = this._mode.decrypt(this, chunk);
	    this.push(thing);
	  }
	  next();
	};
	Decipher.prototype._flush = function (next) {
	  var chunk = this._cache.flush();
	  if (!chunk) {
	    return next;
	  }
	
	  this.push(unpad(this._mode.decrypt(this, chunk)));
	
	  next();
	};
	
	function Splitter() {
	   if (!(this instanceof Splitter)) {
	    return new Splitter();
	  }
	  this.cache = new Buffer('');
	}
	Splitter.prototype.add = function (data) {
	  this.cache = Buffer.concat([this.cache, data]);
	};
	
	Splitter.prototype.get = function () {
	  if (this.cache.length > 16) {
	    var out = this.cache.slice(0, 16);
	    this.cache = this.cache.slice(16);
	    return out;
	  }
	  return null;
	};
	Splitter.prototype.flush = function () {
	  if (this.cache.length) {
	    return this.cache;
	  }
	};
	function unpad(last) {
	  var padded = last[15];
	  if (padded === 16) {
	    return;
	  }
	  return last.slice(0, 16 - padded);
	}
	
	var modelist = {
	  ECB: __webpack_require__(64),
	  CBC: __webpack_require__(65),
	  CFB: __webpack_require__(67),
	  OFB: __webpack_require__(68),
	  CTR: __webpack_require__(69)
	};
	
	module.exports = function (crypto) {
	  function createDecipheriv(suite, password, iv) {
	    var config = modes[suite];
	    if (!config) {
	      throw new TypeError('invalid suite type');
	    }
	    if (typeof iv === 'string') {
	      iv = new Buffer(iv);
	    }
	    if (typeof password === 'string') {
	      password = new Buffer(password);
	    }
	    if (password.length !== config.key/8) {
	      throw new TypeError('invalid key length ' + password.length);
	    }
	    if (iv.length !== config.iv) {
	      throw new TypeError('invalid iv length ' + iv.length);
	    }
	    if (config.type === 'stream') {
	      return new StreamCipher(modelist[config.mode], password, iv, true);
	    }
	    return new Decipher(modelist[config.mode], password, iv);
	  }
	
	  function createDecipher (suite, password) {
	    var config = modes[suite];
	    if (!config) {
	      throw new TypeError('invalid suite type');
	    }
	    var keys = ebtk(crypto, password, config.key, config.iv);
	    return createDecipheriv(suite, keys.key, keys.iv);
	  }
	  return {
	    createDecipher: createDecipher,
	    createDecipheriv: createDecipheriv
	  };
	};
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(12).Buffer))

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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A runtime object which captures compile-time type information.
	 *
	 * #### Notes
	 * A token captures the compile-time type of an interface or class in
	 * an object which can be used at runtime in a type-safe fashion.
	 */
	var Token = (function () {
	    /**
	     * Construct a new token.
	     *
	     * @param name - A human readable name for the token.
	     */
	    function Token(name) {
	        this.name = name;
	        this._tokenStructuralPropertyT = null;
	    }
	    return Token;
	}());
	exports.Token = Token;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var random_1 = __webpack_require__(10);
	/**
	 * The namespace for UUID related functionality.
	 */
	var UUID;
	(function (UUID) {
	    /**
	     * A function which generates UUID v4 identifiers.
	     *
	     * @returns A new UUID v4 string.
	     *
	     * #### Notes
	     * This implementation complies with RFC 4122.
	     *
	     * This uses `Random.getRandomValues()` for random bytes, which in
	     * turn will use the underlying `crypto` module of the platform if
	     * it is available. The fallback for randomness is `Math.random`.
	     */
	    UUID.uuid4 = (function () {
	        // Create a 16 byte array to hold the random values.
	        var bytes = new Uint8Array(16);
	        // Create a look up table from bytes to hex strings.
	        var lut = new Array(256);
	        // Pad the single character hex digits with a leading zero.
	        for (var i = 0; i < 16; ++i) {
	            lut[i] = '0' + i.toString(16);
	        }
	        // Populate the rest of the hex digits.
	        for (var i = 16; i < 256; ++i) {
	            lut[i] = i.toString(16);
	        }
	        // Return a function which generates the UUID.
	        return function uuid4() {
	            // Get a new batch of random values.
	            random_1.Random.getRandomValues(bytes);
	            // Set the UUID version number to 4.
	            bytes[6] = 0x40 | (bytes[6] & 0x0F);
	            // Set the clock sequence bit to the RFC spec.
	            bytes[8] = 0x80 | (bytes[8] & 0x3F);
	            // Assemble the UUID string.
	            return (lut[bytes[0]] +
	                lut[bytes[1]] +
	                lut[bytes[2]] +
	                lut[bytes[3]] +
	                '-' +
	                lut[bytes[4]] +
	                lut[bytes[5]] +
	                '-' +
	                lut[bytes[6]] +
	                lut[bytes[7]] +
	                '-' +
	                lut[bytes[8]] +
	                lut[bytes[9]] +
	                '-' +
	                lut[bytes[10]] +
	                lut[bytes[11]] +
	                lut[bytes[12]] +
	                lut[bytes[13]] +
	                lut[bytes[14]] +
	                lut[bytes[15]]);
	        };
	    })();
	})(UUID = exports.UUID || (exports.UUID = {}));


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

	var baseIsEqual = __webpack_require__(74);
	
	/**
	 * Performs a deep comparison between two values to determine if they are
	 * equivalent.
	 *
	 * **Note:** This method supports comparing arrays, array buffers, booleans,
	 * date objects, error objects, maps, numbers, `Object` objects, regexes,
	 * sets, strings, symbols, and typed arrays. `Object` objects are compared
	 * by their own, not inherited, enumerable properties. Functions and DOM
	 * nodes are compared by strict equality, i.e. `===`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to compare.
	 * @param {*} other The other value to compare.
	 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	 * @example
	 *
	 * var object = { 'a': 1 };
	 * var other = { 'a': 1 };
	 *
	 * _.isEqual(object, other);
	 * // => true
	 *
	 * object === other;
	 * // => false
	 */
	function isEqual(value, other) {
	  return baseIsEqual(value, other);
	}
	
	module.exports = isEqual;


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

	var baseIsEqualDeep = __webpack_require__(75),
	    isObjectLike = __webpack_require__(143);
	
	/**
	 * The base implementation of `_.isEqual` which supports partial comparisons
	 * and tracks traversed objects.
	 *
	 * @private
	 * @param {*} value The value to compare.
	 * @param {*} other The other value to compare.
	 * @param {boolean} bitmask The bitmask flags.
	 *  1 - Unordered comparison
	 *  2 - Partial comparison
	 * @param {Function} [customizer] The function to customize comparisons.
	 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
	 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	 */
	function baseIsEqual(value, other, bitmask, customizer, stack) {
	  if (value === other) {
	    return true;
	  }
	  if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
	    return value !== value && other !== other;
	  }
	  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
	}
	
	module.exports = baseIsEqual;


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

	var Stack = __webpack_require__(76),
	    equalArrays = __webpack_require__(120),
	    equalByTag = __webpack_require__(126),
	    equalObjects = __webpack_require__(130),
	    getTag = __webpack_require__(158),
	    isArray = __webpack_require__(134),
	    isBuffer = __webpack_require__(144),
	    isTypedArray = __webpack_require__(148);
	
	/** Used to compose bitmasks for value comparisons. */
	var COMPARE_PARTIAL_FLAG = 1;
	
	/** `Object#toString` result references. */
	var argsTag = '[object Arguments]',
	    arrayTag = '[object Array]',
	    objectTag = '[object Object]';
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * A specialized version of `baseIsEqual` for arrays and objects which performs
	 * deep comparisons and tracks traversed objects enabling objects with circular
	 * references to be compared.
	 *
	 * @private
	 * @param {Object} object The object to compare.
	 * @param {Object} other The other object to compare.
	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	 * @param {Function} customizer The function to customize comparisons.
	 * @param {Function} equalFunc The function to determine equivalents of values.
	 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
	 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	 */
	function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
	  var objIsArr = isArray(object),
	      othIsArr = isArray(other),
	      objTag = objIsArr ? arrayTag : getTag(object),
	      othTag = othIsArr ? arrayTag : getTag(other);
	
	  objTag = objTag == argsTag ? objectTag : objTag;
	  othTag = othTag == argsTag ? objectTag : othTag;
	
	  var objIsObj = objTag == objectTag,
	      othIsObj = othTag == objectTag,
	      isSameTag = objTag == othTag;
	
	  if (isSameTag && isBuffer(object)) {
	    if (!isBuffer(other)) {
	      return false;
	    }
	    objIsArr = true;
	    objIsObj = false;
	  }
	  if (isSameTag && !objIsObj) {
	    stack || (stack = new Stack);
	    return (objIsArr || isTypedArray(object))
	      ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
	      : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
	  }
	  if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
	    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
	        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
	
	    if (objIsWrapped || othIsWrapped) {
	      var objUnwrapped = objIsWrapped ? object.value() : object,
	          othUnwrapped = othIsWrapped ? other.value() : other;
	
	      stack || (stack = new Stack);
	      return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
	    }
	  }
	  if (!isSameTag) {
	    return false;
	  }
	  stack || (stack = new Stack);
	  return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
	}
	
	module.exports = baseIsEqualDeep;


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

	var ListCache = __webpack_require__(77),
	    stackClear = __webpack_require__(85),
	    stackDelete = __webpack_require__(86),
	    stackGet = __webpack_require__(87),
	    stackHas = __webpack_require__(88),
	    stackSet = __webpack_require__(89);
	
	/**
	 * Creates a stack cache object to store key-value pairs.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function Stack(entries) {
	  var data = this.__data__ = new ListCache(entries);
	  this.size = data.size;
	}
	
	// Add methods to `Stack`.
	Stack.prototype.clear = stackClear;
	Stack.prototype['delete'] = stackDelete;
	Stack.prototype.get = stackGet;
	Stack.prototype.has = stackHas;
	Stack.prototype.set = stackSet;
	
	module.exports = Stack;


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

	var listCacheClear = __webpack_require__(78),
	    listCacheDelete = __webpack_require__(79),
	    listCacheGet = __webpack_require__(82),
	    listCacheHas = __webpack_require__(83),
	    listCacheSet = __webpack_require__(84);
	
	/**
	 * Creates an list cache object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function ListCache(entries) {
	  var index = -1,
	      length = entries == null ? 0 : entries.length;
	
	  this.clear();
	  while (++index < length) {
	    var entry = entries[index];
	    this.set(entry[0], entry[1]);
	  }
	}
	
	// Add methods to `ListCache`.
	ListCache.prototype.clear = listCacheClear;
	ListCache.prototype['delete'] = listCacheDelete;
	ListCache.prototype.get = listCacheGet;
	ListCache.prototype.has = listCacheHas;
	ListCache.prototype.set = listCacheSet;
	
	module.exports = ListCache;


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

	/**
	 * Removes all key-value entries from the list cache.
	 *
	 * @private
	 * @name clear
	 * @memberOf ListCache
	 */
	function listCacheClear() {
	  this.__data__ = [];
	  this.size = 0;
	}
	
	module.exports = listCacheClear;


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

	var assocIndexOf = __webpack_require__(80);
	
	/** Used for built-in method references. */
	var arrayProto = Array.prototype;
	
	/** Built-in value references. */
	var splice = arrayProto.splice;
	
	/**
	 * Removes `key` and its value from the list cache.
	 *
	 * @private
	 * @name delete
	 * @memberOf ListCache
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
	function listCacheDelete(key) {
	  var data = this.__data__,
	      index = assocIndexOf(data, key);
	
	  if (index < 0) {
	    return false;
	  }
	  var lastIndex = data.length - 1;
	  if (index == lastIndex) {
	    data.pop();
	  } else {
	    splice.call(data, index, 1);
	  }
	  --this.size;
	  return true;
	}
	
	module.exports = listCacheDelete;


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

	var eq = __webpack_require__(81);
	
	/**
	 * Gets the index at which the `key` is found in `array` of key-value pairs.
	 *
	 * @private
	 * @param {Array} array The array to inspect.
	 * @param {*} key The key to search for.
	 * @returns {number} Returns the index of the matched value, else `-1`.
	 */
	function assocIndexOf(array, key) {
	  var length = array.length;
	  while (length--) {
	    if (eq(array[length][0], key)) {
	      return length;
	    }
	  }
	  return -1;
	}
	
	module.exports = assocIndexOf;


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

	/**
	 * Performs a
	 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	 * comparison between two values to determine if they are equivalent.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to compare.
	 * @param {*} other The other value to compare.
	 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	 * @example
	 *
	 * var object = { 'a': 1 };
	 * var other = { 'a': 1 };
	 *
	 * _.eq(object, object);
	 * // => true
	 *
	 * _.eq(object, other);
	 * // => false
	 *
	 * _.eq('a', 'a');
	 * // => true
	 *
	 * _.eq('a', Object('a'));
	 * // => false
	 *
	 * _.eq(NaN, NaN);
	 * // => true
	 */
	function eq(value, other) {
	  return value === other || (value !== value && other !== other);
	}
	
	module.exports = eq;


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

	var assocIndexOf = __webpack_require__(80);
	
	/**
	 * Gets the list cache value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf ListCache
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function listCacheGet(key) {
	  var data = this.__data__,
	      index = assocIndexOf(data, key);
	
	  return index < 0 ? undefined : data[index][1];
	}
	
	module.exports = listCacheGet;


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

	var assocIndexOf = __webpack_require__(80);
	
	/**
	 * Checks if a list cache value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf ListCache
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function listCacheHas(key) {
	  return assocIndexOf(this.__data__, key) > -1;
	}
	
	module.exports = listCacheHas;


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

	var assocIndexOf = __webpack_require__(80);
	
	/**
	 * Sets the list cache `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf ListCache
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the list cache instance.
	 */
	function listCacheSet(key, value) {
	  var data = this.__data__,
	      index = assocIndexOf(data, key);
	
	  if (index < 0) {
	    ++this.size;
	    data.push([key, value]);
	  } else {
	    data[index][1] = value;
	  }
	  return this;
	}
	
	module.exports = listCacheSet;


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

	var ListCache = __webpack_require__(77);
	
	/**
	 * Removes all key-value entries from the stack.
	 *
	 * @private
	 * @name clear
	 * @memberOf Stack
	 */
	function stackClear() {
	  this.__data__ = new ListCache;
	  this.size = 0;
	}
	
	module.exports = stackClear;


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

	/**
	 * Removes `key` and its value from the stack.
	 *
	 * @private
	 * @name delete
	 * @memberOf Stack
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
	function stackDelete(key) {
	  var data = this.__data__,
	      result = data['delete'](key);
	
	  this.size = data.size;
	  return result;
	}
	
	module.exports = stackDelete;


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

	/**
	 * Gets the stack value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf Stack
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function stackGet(key) {
	  return this.__data__.get(key);
	}
	
	module.exports = stackGet;


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

	/**
	 * Checks if a stack value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf Stack
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function stackHas(key) {
	  return this.__data__.has(key);
	}
	
	module.exports = stackHas;


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

	var ListCache = __webpack_require__(77),
	    Map = __webpack_require__(90),
	    MapCache = __webpack_require__(105);
	
	/** Used as the size to enable large array optimizations. */
	var LARGE_ARRAY_SIZE = 200;
	
	/**
	 * Sets the stack `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf Stack
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the stack cache instance.
	 */
	function stackSet(key, value) {
	  var data = this.__data__;
	  if (data instanceof ListCache) {
	    var pairs = data.__data__;
	    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
	      pairs.push([key, value]);
	      this.size = ++data.size;
	      return this;
	    }
	    data = this.__data__ = new MapCache(pairs);
	  }
	  data.set(key, value);
	  this.size = data.size;
	  return this;
	}
	
	module.exports = stackSet;


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

	var getNative = __webpack_require__(91),
	    root = __webpack_require__(96);
	
	/* Built-in method references that are verified to be native. */
	var Map = getNative(root, 'Map');
	
	module.exports = Map;


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

	var baseIsNative = __webpack_require__(92),
	    getValue = __webpack_require__(104);
	
	/**
	 * Gets the native function at `key` of `object`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @param {string} key The key of the method to get.
	 * @returns {*} Returns the function if it's native, else `undefined`.
	 */
	function getNative(object, key) {
	  var value = getValue(object, key);
	  return baseIsNative(value) ? value : undefined;
	}
	
	module.exports = getNative;


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

	var isFunction = __webpack_require__(93),
	    isMasked = __webpack_require__(101),
	    isObject = __webpack_require__(100),
	    toSource = __webpack_require__(103);
	
	/**
	 * Used to match `RegExp`
	 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
	 */
	var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
	
	/** Used to detect host constructors (Safari). */
	var reIsHostCtor = /^\[object .+?Constructor\]$/;
	
	/** Used for built-in method references. */
	var funcProto = Function.prototype,
	    objectProto = Object.prototype;
	
	/** Used to resolve the decompiled source of functions. */
	var funcToString = funcProto.toString;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/** Used to detect if a method is native. */
	var reIsNative = RegExp('^' +
	  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
	  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
	);
	
	/**
	 * The base implementation of `_.isNative` without bad shim checks.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a native function,
	 *  else `false`.
	 */
	function baseIsNative(value) {
	  if (!isObject(value) || isMasked(value)) {
	    return false;
	  }
	  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
	  return pattern.test(toSource(value));
	}
	
	module.exports = baseIsNative;


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

	var baseGetTag = __webpack_require__(94),
	    isObject = __webpack_require__(100);
	
	/** `Object#toString` result references. */
	var asyncTag = '[object AsyncFunction]',
	    funcTag = '[object Function]',
	    genTag = '[object GeneratorFunction]',
	    proxyTag = '[object Proxy]';
	
	/**
	 * Checks if `value` is classified as a `Function` object.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
	 * @example
	 *
	 * _.isFunction(_);
	 * // => true
	 *
	 * _.isFunction(/abc/);
	 * // => false
	 */
	function isFunction(value) {
	  if (!isObject(value)) {
	    return false;
	  }
	  // The use of `Object#toString` avoids issues with the `typeof` operator
	  // in Safari 9 which returns 'object' for typed arrays and other constructors.
	  var tag = baseGetTag(value);
	  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
	}
	
	module.exports = isFunction;


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

	var Symbol = __webpack_require__(95),
	    getRawTag = __webpack_require__(98),
	    objectToString = __webpack_require__(99);
	
	/** `Object#toString` result references. */
	var nullTag = '[object Null]',
	    undefinedTag = '[object Undefined]';
	
	/** Built-in value references. */
	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
	
	/**
	 * The base implementation of `getTag` without fallbacks for buggy environments.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @returns {string} Returns the `toStringTag`.
	 */
	function baseGetTag(value) {
	  if (value == null) {
	    return value === undefined ? undefinedTag : nullTag;
	  }
	  return (symToStringTag && symToStringTag in Object(value))
	    ? getRawTag(value)
	    : objectToString(value);
	}
	
	module.exports = baseGetTag;


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

	var root = __webpack_require__(96);
	
	/** Built-in value references. */
	var Symbol = root.Symbol;
	
	module.exports = Symbol;


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

	var freeGlobal = __webpack_require__(97);
	
	/** Detect free variable `self`. */
	var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
	
	/** Used as a reference to the global object. */
	var root = freeGlobal || freeSelf || Function('return this')();
	
	module.exports = root;


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

	/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */
	var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
	
	module.exports = freeGlobal;
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

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

	var Symbol = __webpack_require__(95);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
	var nativeObjectToString = objectProto.toString;
	
	/** Built-in value references. */
	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
	
	/**
	 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @returns {string} Returns the raw `toStringTag`.
	 */
	function getRawTag(value) {
	  var isOwn = hasOwnProperty.call(value, symToStringTag),
	      tag = value[symToStringTag];
	
	  try {
	    value[symToStringTag] = undefined;
	    var unmasked = true;
	  } catch (e) {}
	
	  var result = nativeObjectToString.call(value);
	  if (unmasked) {
	    if (isOwn) {
	      value[symToStringTag] = tag;
	    } else {
	      delete value[symToStringTag];
	    }
	  }
	  return result;
	}
	
	module.exports = getRawTag;


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

	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
	var nativeObjectToString = objectProto.toString;
	
	/**
	 * Converts `value` to a string using `Object.prototype.toString`.
	 *
	 * @private
	 * @param {*} value The value to convert.
	 * @returns {string} Returns the converted string.
	 */
	function objectToString(value) {
	  return nativeObjectToString.call(value);
	}
	
	module.exports = objectToString;


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

	/**
	 * Checks if `value` is the
	 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
	 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
	 * @example
	 *
	 * _.isObject({});
	 * // => true
	 *
	 * _.isObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isObject(_.noop);
	 * // => true
	 *
	 * _.isObject(null);
	 * // => false
	 */
	function isObject(value) {
	  var type = typeof value;
	  return value != null && (type == 'object' || type == 'function');
	}
	
	module.exports = isObject;


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

	var coreJsData = __webpack_require__(102);
	
	/** Used to detect methods masquerading as native. */
	var maskSrcKey = (function() {
	  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
	  return uid ? ('Symbol(src)_1.' + uid) : '';
	}());
	
	/**
	 * Checks if `func` has its source masked.
	 *
	 * @private
	 * @param {Function} func The function to check.
	 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
	 */
	function isMasked(func) {
	  return !!maskSrcKey && (maskSrcKey in func);
	}
	
	module.exports = isMasked;


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

	var root = __webpack_require__(96);
	
	/** Used to detect overreaching core-js shims. */
	var coreJsData = root['__core-js_shared__'];
	
	module.exports = coreJsData;


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

	/** Used for built-in method references. */
	var funcProto = Function.prototype;
	
	/** Used to resolve the decompiled source of functions. */
	var funcToString = funcProto.toString;
	
	/**
	 * Converts `func` to its source code.
	 *
	 * @private
	 * @param {Function} func The function to convert.
	 * @returns {string} Returns the source code.
	 */
	function toSource(func) {
	  if (func != null) {
	    try {
	      return funcToString.call(func);
	    } catch (e) {}
	    try {
	      return (func + '');
	    } catch (e) {}
	  }
	  return '';
	}
	
	module.exports = toSource;


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

	/**
	 * Gets the value at `key` of `object`.
	 *
	 * @private
	 * @param {Object} [object] The object to query.
	 * @param {string} key The key of the property to get.
	 * @returns {*} Returns the property value.
	 */
	function getValue(object, key) {
	  return object == null ? undefined : object[key];
	}
	
	module.exports = getValue;


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

	var mapCacheClear = __webpack_require__(106),
	    mapCacheDelete = __webpack_require__(114),
	    mapCacheGet = __webpack_require__(117),
	    mapCacheHas = __webpack_require__(118),
	    mapCacheSet = __webpack_require__(119);
	
	/**
	 * Creates a map cache object to store key-value pairs.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function MapCache(entries) {
	  var index = -1,
	      length = entries == null ? 0 : entries.length;
	
	  this.clear();
	  while (++index < length) {
	    var entry = entries[index];
	    this.set(entry[0], entry[1]);
	  }
	}
	
	// Add methods to `MapCache`.
	MapCache.prototype.clear = mapCacheClear;
	MapCache.prototype['delete'] = mapCacheDelete;
	MapCache.prototype.get = mapCacheGet;
	MapCache.prototype.has = mapCacheHas;
	MapCache.prototype.set = mapCacheSet;
	
	module.exports = MapCache;


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

	var Hash = __webpack_require__(107),
	    ListCache = __webpack_require__(77),
	    Map = __webpack_require__(90);
	
	/**
	 * Removes all key-value entries from the map.
	 *
	 * @private
	 * @name clear
	 * @memberOf MapCache
	 */
	function mapCacheClear() {
	  this.size = 0;
	  this.__data__ = {
	    'hash': new Hash,
	    'map': new (Map || ListCache),
	    'string': new Hash
	  };
	}
	
	module.exports = mapCacheClear;


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

	var hashClear = __webpack_require__(108),
	    hashDelete = __webpack_require__(110),
	    hashGet = __webpack_require__(111),
	    hashHas = __webpack_require__(112),
	    hashSet = __webpack_require__(113);
	
	/**
	 * Creates a hash object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function Hash(entries) {
	  var index = -1,
	      length = entries == null ? 0 : entries.length;
	
	  this.clear();
	  while (++index < length) {
	    var entry = entries[index];
	    this.set(entry[0], entry[1]);
	  }
	}
	
	// Add methods to `Hash`.
	Hash.prototype.clear = hashClear;
	Hash.prototype['delete'] = hashDelete;
	Hash.prototype.get = hashGet;
	Hash.prototype.has = hashHas;
	Hash.prototype.set = hashSet;
	
	module.exports = Hash;


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

	var nativeCreate = __webpack_require__(109);
	
	/**
	 * Removes all key-value entries from the hash.
	 *
	 * @private
	 * @name clear
	 * @memberOf Hash
	 */
	function hashClear() {
	  this.__data__ = nativeCreate ? nativeCreate(null) : {};
	  this.size = 0;
	}
	
	module.exports = hashClear;


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

	var getNative = __webpack_require__(91);
	
	/* Built-in method references that are verified to be native. */
	var nativeCreate = getNative(Object, 'create');
	
	module.exports = nativeCreate;


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

	/**
	 * Removes `key` and its value from the hash.
	 *
	 * @private
	 * @name delete
	 * @memberOf Hash
	 * @param {Object} hash The hash to modify.
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
	function hashDelete(key) {
	  var result = this.has(key) && delete this.__data__[key];
	  this.size -= result ? 1 : 0;
	  return result;
	}
	
	module.exports = hashDelete;


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

	var nativeCreate = __webpack_require__(109);
	
	/** Used to stand-in for `undefined` hash values. */
	var HASH_UNDEFINED = '__lodash_hash_undefined__';
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * Gets the hash value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf Hash
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function hashGet(key) {
	  var data = this.__data__;
	  if (nativeCreate) {
	    var result = data[key];
	    return result === HASH_UNDEFINED ? undefined : result;
	  }
	  return hasOwnProperty.call(data, key) ? data[key] : undefined;
	}
	
	module.exports = hashGet;


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

	var nativeCreate = __webpack_require__(109);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * Checks if a hash value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf Hash
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function hashHas(key) {
	  var data = this.__data__;
	  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
	}
	
	module.exports = hashHas;


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

	var nativeCreate = __webpack_require__(109);
	
	/** Used to stand-in for `undefined` hash values. */
	var HASH_UNDEFINED = '__lodash_hash_undefined__';
	
	/**
	 * Sets the hash `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf Hash
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the hash instance.
	 */
	function hashSet(key, value) {
	  var data = this.__data__;
	  this.size += this.has(key) ? 0 : 1;
	  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
	  return this;
	}
	
	module.exports = hashSet;


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

	var getMapData = __webpack_require__(115);
	
	/**
	 * Removes `key` and its value from the map.
	 *
	 * @private
	 * @name delete
	 * @memberOf MapCache
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
	function mapCacheDelete(key) {
	  var result = getMapData(this, key)['delete'](key);
	  this.size -= result ? 1 : 0;
	  return result;
	}
	
	module.exports = mapCacheDelete;


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

	var isKeyable = __webpack_require__(116);
	
	/**
	 * Gets the data for `map`.
	 *
	 * @private
	 * @param {Object} map The map to query.
	 * @param {string} key The reference key.
	 * @returns {*} Returns the map data.
	 */
	function getMapData(map, key) {
	  var data = map.__data__;
	  return isKeyable(key)
	    ? data[typeof key == 'string' ? 'string' : 'hash']
	    : data.map;
	}
	
	module.exports = getMapData;


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

	/**
	 * Checks if `value` is suitable for use as unique object key.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
	 */
	function isKeyable(value) {
	  var type = typeof value;
	  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
	    ? (value !== '__proto__')
	    : (value === null);
	}
	
	module.exports = isKeyable;


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

	var getMapData = __webpack_require__(115);
	
	/**
	 * Gets the map value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf MapCache
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function mapCacheGet(key) {
	  return getMapData(this, key).get(key);
	}
	
	module.exports = mapCacheGet;


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

	var getMapData = __webpack_require__(115);
	
	/**
	 * Checks if a map value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf MapCache
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function mapCacheHas(key) {
	  return getMapData(this, key).has(key);
	}
	
	module.exports = mapCacheHas;


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

	var getMapData = __webpack_require__(115);
	
	/**
	 * Sets the map `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf MapCache
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the map cache instance.
	 */
	function mapCacheSet(key, value) {
	  var data = getMapData(this, key),
	      size = data.size;
	
	  data.set(key, value);
	  this.size += data.size == size ? 0 : 1;
	  return this;
	}
	
	module.exports = mapCacheSet;


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

	var SetCache = __webpack_require__(121),
	    arraySome = __webpack_require__(124),
	    cacheHas = __webpack_require__(125);
	
	/** Used to compose bitmasks for value comparisons. */
	var COMPARE_PARTIAL_FLAG = 1,
	    COMPARE_UNORDERED_FLAG = 2;
	
	/**
	 * A specialized version of `baseIsEqualDeep` for arrays with support for
	 * partial deep comparisons.
	 *
	 * @private
	 * @param {Array} array The array to compare.
	 * @param {Array} other The other array to compare.
	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	 * @param {Function} customizer The function to customize comparisons.
	 * @param {Function} equalFunc The function to determine equivalents of values.
	 * @param {Object} stack Tracks traversed `array` and `other` objects.
	 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
	 */
	function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
	  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
	      arrLength = array.length,
	      othLength = other.length;
	
	  if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
	    return false;
	  }
	  // Assume cyclic values are equal.
	  var stacked = stack.get(array);
	  if (stacked && stack.get(other)) {
	    return stacked == other;
	  }
	  var index = -1,
	      result = true,
	      seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
	
	  stack.set(array, other);
	  stack.set(other, array);
	
	  // Ignore non-index properties.
	  while (++index < arrLength) {
	    var arrValue = array[index],
	        othValue = other[index];
	
	    if (customizer) {
	      var compared = isPartial
	        ? customizer(othValue, arrValue, index, other, array, stack)
	        : customizer(arrValue, othValue, index, array, other, stack);
	    }
	    if (compared !== undefined) {
	      if (compared) {
	        continue;
	      }
	      result = false;
	      break;
	    }
	    // Recursively compare arrays (susceptible to call stack limits).
	    if (seen) {
	      if (!arraySome(other, function(othValue, othIndex) {
	            if (!cacheHas(seen, othIndex) &&
	                (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
	              return seen.push(othIndex);
	            }
	          })) {
	        result = false;
	        break;
	      }
	    } else if (!(
	          arrValue === othValue ||
	            equalFunc(arrValue, othValue, bitmask, customizer, stack)
	        )) {
	      result = false;
	      break;
	    }
	  }
	  stack['delete'](array);
	  stack['delete'](other);
	  return result;
	}
	
	module.exports = equalArrays;


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

	var MapCache = __webpack_require__(105),
	    setCacheAdd = __webpack_require__(122),
	    setCacheHas = __webpack_require__(123);
	
	/**
	 *
	 * Creates an array cache object to store unique values.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [values] The values to cache.
	 */
	function SetCache(values) {
	  var index = -1,
	      length = values == null ? 0 : values.length;
	
	  this.__data__ = new MapCache;
	  while (++index < length) {
	    this.add(values[index]);
	  }
	}
	
	// Add methods to `SetCache`.
	SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
	SetCache.prototype.has = setCacheHas;
	
	module.exports = SetCache;


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

	/** Used to stand-in for `undefined` hash values. */
	var HASH_UNDEFINED = '__lodash_hash_undefined__';
	
	/**
	 * Adds `value` to the array cache.
	 *
	 * @private
	 * @name add
	 * @memberOf SetCache
	 * @alias push
	 * @param {*} value The value to cache.
	 * @returns {Object} Returns the cache instance.
	 */
	function setCacheAdd(value) {
	  this.__data__.set(value, HASH_UNDEFINED);
	  return this;
	}
	
	module.exports = setCacheAdd;


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

	/**
	 * Checks if `value` is in the array cache.
	 *
	 * @private
	 * @name has
	 * @memberOf SetCache
	 * @param {*} value The value to search for.
	 * @returns {number} Returns `true` if `value` is found, else `false`.
	 */
	function setCacheHas(value) {
	  return this.__data__.has(value);
	}
	
	module.exports = setCacheHas;


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

	/**
	 * A specialized version of `_.some` for arrays without support for iteratee
	 * shorthands.
	 *
	 * @private
	 * @param {Array} [array] The array to iterate over.
	 * @param {Function} predicate The function invoked per iteration.
	 * @returns {boolean} Returns `true` if any element passes the predicate check,
	 *  else `false`.
	 */
	function arraySome(array, predicate) {
	  var index = -1,
	      length = array == null ? 0 : array.length;
	
	  while (++index < length) {
	    if (predicate(array[index], index, array)) {
	      return true;
	    }
	  }
	  return false;
	}
	
	module.exports = arraySome;


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

	/**
	 * Checks if a `cache` value for `key` exists.
	 *
	 * @private
	 * @param {Object} cache The cache to query.
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function cacheHas(cache, key) {
	  return cache.has(key);
	}
	
	module.exports = cacheHas;


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

	var Symbol = __webpack_require__(95),
	    Uint8Array = __webpack_require__(127),
	    eq = __webpack_require__(81),
	    equalArrays = __webpack_require__(120),
	    mapToArray = __webpack_require__(128),
	    setToArray = __webpack_require__(129);
	
	/** Used to compose bitmasks for value comparisons. */
	var COMPARE_PARTIAL_FLAG = 1,
	    COMPARE_UNORDERED_FLAG = 2;
	
	/** `Object#toString` result references. */
	var boolTag = '[object Boolean]',
	    dateTag = '[object Date]',
	    errorTag = '[object Error]',
	    mapTag = '[object Map]',
	    numberTag = '[object Number]',
	    regexpTag = '[object RegExp]',
	    setTag = '[object Set]',
	    stringTag = '[object String]',
	    symbolTag = '[object Symbol]';
	
	var arrayBufferTag = '[object ArrayBuffer]',
	    dataViewTag = '[object DataView]';
	
	/** Used to convert symbols to primitives and strings. */
	var symbolProto = Symbol ? Symbol.prototype : undefined,
	    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
	
	/**
	 * A specialized version of `baseIsEqualDeep` for comparing objects of
	 * the same `toStringTag`.
	 *
	 * **Note:** This function only supports comparing values with tags of
	 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
	 *
	 * @private
	 * @param {Object} object The object to compare.
	 * @param {Object} other The other object to compare.
	 * @param {string} tag The `toStringTag` of the objects to compare.
	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	 * @param {Function} customizer The function to customize comparisons.
	 * @param {Function} equalFunc The function to determine equivalents of values.
	 * @param {Object} stack Tracks traversed `object` and `other` objects.
	 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	 */
	function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
	  switch (tag) {
	    case dataViewTag:
	      if ((object.byteLength != other.byteLength) ||
	          (object.byteOffset != other.byteOffset)) {
	        return false;
	      }
	      object = object.buffer;
	      other = other.buffer;
	
	    case arrayBufferTag:
	      if ((object.byteLength != other.byteLength) ||
	          !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
	        return false;
	      }
	      return true;
	
	    case boolTag:
	    case dateTag:
	    case numberTag:
	      // Coerce booleans to `1` or `0` and dates to milliseconds.
	      // Invalid dates are coerced to `NaN`.
	      return eq(+object, +other);
	
	    case errorTag:
	      return object.name == other.name && object.message == other.message;
	
	    case regexpTag:
	    case stringTag:
	      // Coerce regexes to strings and treat strings, primitives and objects,
	      // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
	      // for more details.
	      return object == (other + '');
	
	    case mapTag:
	      var convert = mapToArray;
	
	    case setTag:
	      var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
	      convert || (convert = setToArray);
	
	      if (object.size != other.size && !isPartial) {
	        return false;
	      }
	      // Assume cyclic values are equal.
	      var stacked = stack.get(object);
	      if (stacked) {
	        return stacked == other;
	      }
	      bitmask |= COMPARE_UNORDERED_FLAG;
	
	      // Recursively compare objects (susceptible to call stack limits).
	      stack.set(object, other);
	      var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
	      stack['delete'](object);
	      return result;
	
	    case symbolTag:
	      if (symbolValueOf) {
	        return symbolValueOf.call(object) == symbolValueOf.call(other);
	      }
	  }
	  return false;
	}
	
	module.exports = equalByTag;


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

	var root = __webpack_require__(96);
	
	/** Built-in value references. */
	var Uint8Array = root.Uint8Array;
	
	module.exports = Uint8Array;


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

	/**
	 * Converts `map` to its key-value pairs.
	 *
	 * @private
	 * @param {Object} map The map to convert.
	 * @returns {Array} Returns the key-value pairs.
	 */
	function mapToArray(map) {
	  var index = -1,
	      result = Array(map.size);
	
	  map.forEach(function(value, key) {
	    result[++index] = [key, value];
	  });
	  return result;
	}
	
	module.exports = mapToArray;


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

	/**
	 * Converts `set` to an array of its values.
	 *
	 * @private
	 * @param {Object} set The set to convert.
	 * @returns {Array} Returns the values.
	 */
	function setToArray(set) {
	  var index = -1,
	      result = Array(set.size);
	
	  set.forEach(function(value) {
	    result[++index] = value;
	  });
	  return result;
	}
	
	module.exports = setToArray;


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

	var getAllKeys = __webpack_require__(131);
	
	/** Used to compose bitmasks for value comparisons. */
	var COMPARE_PARTIAL_FLAG = 1;
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * A specialized version of `baseIsEqualDeep` for objects with support for
	 * partial deep comparisons.
	 *
	 * @private
	 * @param {Object} object The object to compare.
	 * @param {Object} other The other object to compare.
	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	 * @param {Function} customizer The function to customize comparisons.
	 * @param {Function} equalFunc The function to determine equivalents of values.
	 * @param {Object} stack Tracks traversed `object` and `other` objects.
	 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	 */
	function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
	  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
	      objProps = getAllKeys(object),
	      objLength = objProps.length,
	      othProps = getAllKeys(other),
	      othLength = othProps.length;
	
	  if (objLength != othLength && !isPartial) {
	    return false;
	  }
	  var index = objLength;
	  while (index--) {
	    var key = objProps[index];
	    if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
	      return false;
	    }
	  }
	  // Assume cyclic values are equal.
	  var stacked = stack.get(object);
	  if (stacked && stack.get(other)) {
	    return stacked == other;
	  }
	  var result = true;
	  stack.set(object, other);
	  stack.set(other, object);
	
	  var skipCtor = isPartial;
	  while (++index < objLength) {
	    key = objProps[index];
	    var objValue = object[key],
	        othValue = other[key];
	
	    if (customizer) {
	      var compared = isPartial
	        ? customizer(othValue, objValue, key, other, object, stack)
	        : customizer(objValue, othValue, key, object, other, stack);
	    }
	    // Recursively compare objects (susceptible to call stack limits).
	    if (!(compared === undefined
	          ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
	          : compared
	        )) {
	      result = false;
	      break;
	    }
	    skipCtor || (skipCtor = key == 'constructor');
	  }
	  if (result && !skipCtor) {
	    var objCtor = object.constructor,
	        othCtor = other.constructor;
	
	    // Non `Object` object instances with different constructors are not equal.
	    if (objCtor != othCtor &&
	        ('constructor' in object && 'constructor' in other) &&
	        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
	          typeof othCtor == 'function' && othCtor instanceof othCtor)) {
	      result = false;
	    }
	  }
	  stack['delete'](object);
	  stack['delete'](other);
	  return result;
	}
	
	module.exports = equalObjects;


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

	var baseGetAllKeys = __webpack_require__(132),
	    getSymbols = __webpack_require__(135),
	    keys = __webpack_require__(138);
	
	/**
	 * Creates an array of own enumerable property names and symbols of `object`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names and symbols.
	 */
	function getAllKeys(object) {
	  return baseGetAllKeys(object, keys, getSymbols);
	}
	
	module.exports = getAllKeys;


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

	var arrayPush = __webpack_require__(133),
	    isArray = __webpack_require__(134);
	
	/**
	 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
	 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
	 * symbols of `object`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @param {Function} keysFunc The function to get the keys of `object`.
	 * @param {Function} symbolsFunc The function to get the symbols of `object`.
	 * @returns {Array} Returns the array of property names and symbols.
	 */
	function baseGetAllKeys(object, keysFunc, symbolsFunc) {
	  var result = keysFunc(object);
	  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
	}
	
	module.exports = baseGetAllKeys;


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

	/**
	 * Appends the elements of `values` to `array`.
	 *
	 * @private
	 * @param {Array} array The array to modify.
	 * @param {Array} values The values to append.
	 * @returns {Array} Returns `array`.
	 */
	function arrayPush(array, values) {
	  var index = -1,
	      length = values.length,
	      offset = array.length;
	
	  while (++index < length) {
	    array[offset + index] = values[index];
	  }
	  return array;
	}
	
	module.exports = arrayPush;


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

	/**
	 * Checks if `value` is classified as an `Array` object.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
	 * @example
	 *
	 * _.isArray([1, 2, 3]);
	 * // => true
	 *
	 * _.isArray(document.body.children);
	 * // => false
	 *
	 * _.isArray('abc');
	 * // => false
	 *
	 * _.isArray(_.noop);
	 * // => false
	 */
	var isArray = Array.isArray;
	
	module.exports = isArray;


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

	var arrayFilter = __webpack_require__(136),
	    stubArray = __webpack_require__(137);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Built-in value references. */
	var propertyIsEnumerable = objectProto.propertyIsEnumerable;
	
	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeGetSymbols = Object.getOwnPropertySymbols;
	
	/**
	 * Creates an array of the own enumerable symbols of `object`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of symbols.
	 */
	var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
	  if (object == null) {
	    return [];
	  }
	  object = Object(object);
	  return arrayFilter(nativeGetSymbols(object), function(symbol) {
	    return propertyIsEnumerable.call(object, symbol);
	  });
	};
	
	module.exports = getSymbols;


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

	/**
	 * A specialized version of `_.filter` for arrays without support for
	 * iteratee shorthands.
	 *
	 * @private
	 * @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 = -1,
	      length = array == null ? 0 : array.length,
	      resIndex = 0,
	      result = [];
	
	  while (++index < length) {
	    var value = array[index];
	    if (predicate(value, index, array)) {
	      result[resIndex++] = value;
	    }
	  }
	  return result;
	}
	
	module.exports = arrayFilter;


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

	/**
	 * This method returns a new empty array.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.13.0
	 * @category Util
	 * @returns {Array} Returns the new empty array.
	 * @example
	 *
	 * var arrays = _.times(2, _.stubArray);
	 *
	 * console.log(arrays);
	 * // => [[], []]
	 *
	 * console.log(arrays[0] === arrays[1]);
	 * // => false
	 */
	function stubArray() {
	  return [];
	}
	
	module.exports = stubArray;


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

	var arrayLikeKeys = __webpack_require__(139),
	    baseKeys = __webpack_require__(153),
	    isArrayLike = __webpack_require__(157);
	
	/**
	 * Creates an array of the own enumerable property names of `object`.
	 *
	 * **Note:** Non-object values are coerced to objects. See the
	 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
	 * for more details.
	 *
	 * @static
	 * @since 0.1.0
	 * @memberOf _
	 * @category Object
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 * @example
	 *
	 * function Foo() {
	 *   this.a = 1;
	 *   this.b = 2;
	 * }
	 *
	 * Foo.prototype.c = 3;
	 *
	 * _.keys(new Foo);
	 * // => ['a', 'b'] (iteration order is not guaranteed)
	 *
	 * _.keys('hi');
	 * // => ['0', '1']
	 */
	function keys(object) {
	  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
	}
	
	module.exports = keys;


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

	var baseTimes = __webpack_require__(140),
	    isArguments = __webpack_require__(141),
	    isArray = __webpack_require__(134),
	    isBuffer = __webpack_require__(144),
	    isIndex = __webpack_require__(147),
	    isTypedArray = __webpack_require__(148);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * Creates an array of the enumerable property names of the array-like `value`.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @param {boolean} inherited Specify returning inherited property names.
	 * @returns {Array} Returns the array of property names.
	 */
	function arrayLikeKeys(value, inherited) {
	  var isArr = isArray(value),
	      isArg = !isArr && isArguments(value),
	      isBuff = !isArr && !isArg && isBuffer(value),
	      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
	      skipIndexes = isArr || isArg || isBuff || isType,
	      result = skipIndexes ? baseTimes(value.length, String) : [],
	      length = result.length;
	
	  for (var key in value) {
	    if ((inherited || hasOwnProperty.call(value, key)) &&
	        !(skipIndexes && (
	           // Safari 9 has enumerable `arguments.length` in strict mode.
	           key == 'length' ||
	           // Node.js 0.10 has enumerable non-index properties on buffers.
	           (isBuff && (key == 'offset' || key == 'parent')) ||
	           // PhantomJS 2 has enumerable non-index properties on typed arrays.
	           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
	           // Skip index properties.
	           isIndex(key, length)
	        ))) {
	      result.push(key);
	    }
	  }
	  return result;
	}
	
	module.exports = arrayLikeKeys;


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

	/**
	 * The base implementation of `_.times` without support for iteratee shorthands
	 * or max array length checks.
	 *
	 * @private
	 * @param {number} n The number of times to invoke `iteratee`.
	 * @param {Function} iteratee The function invoked per iteration.
	 * @returns {Array} Returns the array of results.
	 */
	function baseTimes(n, iteratee) {
	  var index = -1,
	      result = Array(n);
	
	  while (++index < n) {
	    result[index] = iteratee(index);
	  }
	  return result;
	}
	
	module.exports = baseTimes;


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

	var baseIsArguments = __webpack_require__(142),
	    isObjectLike = __webpack_require__(143);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/** Built-in value references. */
	var propertyIsEnumerable = objectProto.propertyIsEnumerable;
	
	/**
	 * Checks if `value` is likely an `arguments` object.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	 *  else `false`.
	 * @example
	 *
	 * _.isArguments(function() { return arguments; }());
	 * // => true
	 *
	 * _.isArguments([1, 2, 3]);
	 * // => false
	 */
	var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
	  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
	    !propertyIsEnumerable.call(value, 'callee');
	};
	
	module.exports = isArguments;


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

	var baseGetTag = __webpack_require__(94),
	    isObjectLike = __webpack_require__(143);
	
	/** `Object#toString` result references. */
	var argsTag = '[object Arguments]';
	
	/**
	 * The base implementation of `_.isArguments`.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	 */
	function baseIsArguments(value) {
	  return isObjectLike(value) && baseGetTag(value) == argsTag;
	}
	
	module.exports = baseIsArguments;


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

	/**
	 * Checks if `value` is object-like. A value is object-like if it's not `null`
	 * and has a `typeof` result of "object".
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
	 * @example
	 *
	 * _.isObjectLike({});
	 * // => true
	 *
	 * _.isObjectLike([1, 2, 3]);
	 * // => true
	 *
	 * _.isObjectLike(_.noop);
	 * // => false
	 *
	 * _.isObjectLike(null);
	 * // => false
	 */
	function isObjectLike(value) {
	  return value != null && typeof value == 'object';
	}
	
	module.exports = isObjectLike;


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

	/* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(96),
	    stubFalse = __webpack_require__(146);
	
	/** Detect free variable `exports`. */
	var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
	
	/** Detect free variable `module`. */
	var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
	
	/** Detect the popular CommonJS extension `module.exports`. */
	var moduleExports = freeModule && freeModule.exports === freeExports;
	
	/** Built-in value references. */
	var Buffer = moduleExports ? root.Buffer : undefined;
	
	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
	
	/**
	 * Checks if `value` is a buffer.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.3.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
	 * @example
	 *
	 * _.isBuffer(new Buffer(2));
	 * // => true
	 *
	 * _.isBuffer(new Uint8Array(2));
	 * // => false
	 */
	var isBuffer = nativeIsBuffer || stubFalse;
	
	module.exports = isBuffer;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(145)(module)))

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

	module.exports = function(module) {
		if(!module.webpackPolyfill) {
			module.deprecate = function() {};
			module.paths = [];
			// module.parent = undefined by default
			module.children = [];
			module.webpackPolyfill = 1;
		}
		return module;
	}


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

	/**
	 * This method returns `false`.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.13.0
	 * @category Util
	 * @returns {boolean} Returns `false`.
	 * @example
	 *
	 * _.times(2, _.stubFalse);
	 * // => [false, false]
	 */
	function stubFalse() {
	  return false;
	}
	
	module.exports = stubFalse;


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

	/** Used as references for various `Number` constants. */
	var MAX_SAFE_INTEGER = 9007199254740991;
	
	/** Used to detect unsigned integer values. */
	var reIsUint = /^(?:0|[1-9]\d*)$/;
	
	/**
	 * Checks if `value` is a valid array-like index.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
	 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
	 */
	function isIndex(value, length) {
	  length = length == null ? MAX_SAFE_INTEGER : length;
	  return !!length &&
	    (typeof value == 'number' || reIsUint.test(value)) &&
	    (value > -1 && value % 1 == 0 && value < length);
	}
	
	module.exports = isIndex;


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

	var baseIsTypedArray = __webpack_require__(149),
	    baseUnary = __webpack_require__(151),
	    nodeUtil = __webpack_require__(152);
	
	/* Node.js helper references. */
	var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
	
	/**
	 * Checks if `value` is classified as a typed array.
	 *
	 * @static
	 * @memberOf _
	 * @since 3.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	 * @example
	 *
	 * _.isTypedArray(new Uint8Array);
	 * // => true
	 *
	 * _.isTypedArray([]);
	 * // => false
	 */
	var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
	
	module.exports = isTypedArray;


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

	var baseGetTag = __webpack_require__(94),
	    isLength = __webpack_require__(150),
	    isObjectLike = __webpack_require__(143);
	
	/** `Object#toString` result references. */
	var argsTag = '[object Arguments]',
	    arrayTag = '[object Array]',
	    boolTag = '[object Boolean]',
	    dateTag = '[object Date]',
	    errorTag = '[object Error]',
	    funcTag = '[object Function]',
	    mapTag = '[object Map]',
	    numberTag = '[object Number]',
	    objectTag = '[object Object]',
	    regexpTag = '[object RegExp]',
	    setTag = '[object Set]',
	    stringTag = '[object String]',
	    weakMapTag = '[object WeakMap]';
	
	var arrayBufferTag = '[object ArrayBuffer]',
	    dataViewTag = '[object DataView]',
	    float32Tag = '[object Float32Array]',
	    float64Tag = '[object Float64Array]',
	    int8Tag = '[object Int8Array]',
	    int16Tag = '[object Int16Array]',
	    int32Tag = '[object Int32Array]',
	    uint8Tag = '[object Uint8Array]',
	    uint8ClampedTag = '[object Uint8ClampedArray]',
	    uint16Tag = '[object Uint16Array]',
	    uint32Tag = '[object Uint32Array]';
	
	/** Used to identify `toStringTag` values of typed arrays. */
	var typedArrayTags = {};
	typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
	typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
	typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
	typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
	typedArrayTags[uint32Tag] = true;
	typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
	typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
	typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
	typedArrayTags[errorTag] = typedArrayTags[funcTag] =
	typedArrayTags[mapTag] = typedArrayTags[numberTag] =
	typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
	typedArrayTags[setTag] = typedArrayTags[stringTag] =
	typedArrayTags[weakMapTag] = false;
	
	/**
	 * The base implementation of `_.isTypedArray` without Node.js optimizations.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	 */
	function baseIsTypedArray(value) {
	  return isObjectLike(value) &&
	    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
	}
	
	module.exports = baseIsTypedArray;


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

	/** Used as references for various `Number` constants. */
	var MAX_SAFE_INTEGER = 9007199254740991;
	
	/**
	 * Checks if `value` is a valid array-like length.
	 *
	 * **Note:** This method is loosely based on
	 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
	 * @example
	 *
	 * _.isLength(3);
	 * // => true
	 *
	 * _.isLength(Number.MIN_VALUE);
	 * // => false
	 *
	 * _.isLength(Infinity);
	 * // => false
	 *
	 * _.isLength('3');
	 * // => false
	 */
	function isLength(value) {
	  return typeof value == 'number' &&
	    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
	}
	
	module.exports = isLength;


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

	/**
	 * The base implementation of `_.unary` without support for storing metadata.
	 *
	 * @private
	 * @param {Function} func The function to cap arguments for.
	 * @returns {Function} Returns the new capped function.
	 */
	function baseUnary(func) {
	  return function(value) {
	    return func(value);
	  };
	}
	
	module.exports = baseUnary;


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

	/* WEBPACK VAR INJECTION */(function(module) {var freeGlobal = __webpack_require__(97);
	
	/** Detect free variable `exports`. */
	var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
	
	/** Detect free variable `module`. */
	var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
	
	/** Detect the popular CommonJS extension `module.exports`. */
	var moduleExports = freeModule && freeModule.exports === freeExports;
	
	/** Detect free variable `process` from Node.js. */
	var freeProcess = moduleExports && freeGlobal.process;
	
	/** Used to access faster Node.js helpers. */
	var nodeUtil = (function() {
	  try {
	    return freeProcess && freeProcess.binding && freeProcess.binding('util');
	  } catch (e) {}
	}());
	
	module.exports = nodeUtil;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(145)(module)))

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

	var isPrototype = __webpack_require__(154),
	    nativeKeys = __webpack_require__(155);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 */
	function baseKeys(object) {
	  if (!isPrototype(object)) {
	    return nativeKeys(object);
	  }
	  var result = [];
	  for (var key in Object(object)) {
	    if (hasOwnProperty.call(object, key) && key != 'constructor') {
	      result.push(key);
	    }
	  }
	  return result;
	}
	
	module.exports = baseKeys;


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

	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/**
	 * Checks if `value` is likely a prototype object.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
	 */
	function isPrototype(value) {
	  var Ctor = value && value.constructor,
	      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
	
	  return value === proto;
	}
	
	module.exports = isPrototype;


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

	var overArg = __webpack_require__(156);
	
	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeKeys = overArg(Object.keys, Object);
	
	module.exports = nativeKeys;


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

	/**
	 * Creates a unary function that invokes `func` with its argument transformed.
	 *
	 * @private
	 * @param {Function} func The function to wrap.
	 * @param {Function} transform The argument transform.
	 * @returns {Function} Returns the new function.
	 */
	function overArg(func, transform) {
	  return function(arg) {
	    return func(transform(arg));
	  };
	}
	
	module.exports = overArg;


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

	var isFunction = __webpack_require__(93),
	    isLength = __webpack_require__(150);
	
	/**
	 * Checks if `value` is array-like. A value is considered array-like if it's
	 * not a function and has a `value.length` that's an integer greater than or
	 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
	 * @example
	 *
	 * _.isArrayLike([1, 2, 3]);
	 * // => true
	 *
	 * _.isArrayLike(document.body.children);
	 * // => true
	 *
	 * _.isArrayLike('abc');
	 * // => true
	 *
	 * _.isArrayLike(_.noop);
	 * // => false
	 */
	function isArrayLike(value) {
	  return value != null && isLength(value.length) && !isFunction(value);
	}
	
	module.exports = isArrayLike;


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

	var DataView = __webpack_require__(159),
	    Map = __webpack_require__(90),
	    Promise = __webpack_require__(160),
	    Set = __webpack_require__(161),
	    WeakMap = __webpack_require__(162),
	    baseGetTag = __webpack_require__(94),
	    toSource = __webpack_require__(103);
	
	/** `Object#toString` result references. */
	var mapTag = '[object Map]',
	    objectTag = '[object Object]',
	    promiseTag = '[object Promise]',
	    setTag = '[object Set]',
	    weakMapTag = '[object WeakMap]';
	
	var dataViewTag = '[object DataView]';
	
	/** Used to detect maps, sets, and weakmaps. */
	var dataViewCtorString = toSource(DataView),
	    mapCtorString = toSource(Map),
	    promiseCtorString = toSource(Promise),
	    setCtorString = toSource(Set),
	    weakMapCtorString = toSource(WeakMap);
	
	/**
	 * Gets the `toStringTag` of `value`.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @returns {string} Returns the `toStringTag`.
	 */
	var getTag = baseGetTag;
	
	// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
	if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
	    (Map && getTag(new Map) != mapTag) ||
	    (Promise && getTag(Promise.resolve()) != promiseTag) ||
	    (Set && getTag(new Set) != setTag) ||
	    (WeakMap && getTag(new WeakMap) != weakMapTag)) {
	  getTag = function(value) {
	    var result = baseGetTag(value),
	        Ctor = result == objectTag ? value.constructor : undefined,
	        ctorString = Ctor ? toSource(Ctor) : '';
	
	    if (ctorString) {
	      switch (ctorString) {
	        case dataViewCtorString: return dataViewTag;
	        case mapCtorString: return mapTag;
	        case promiseCtorString: return promiseTag;
	        case setCtorString: return setTag;
	        case weakMapCtorString: return weakMapTag;
	      }
	    }
	    return result;
	  };
	}
	
	module.exports = getTag;


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

	var getNative = __webpack_require__(91),
	    root = __webpack_require__(96);
	
	/* Built-in method references that are verified to be native. */
	var DataView = getNative(root, 'DataView');
	
	module.exports = DataView;


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

	var getNative = __webpack_require__(91),
	    root = __webpack_require__(96);
	
	/* Built-in method references that are verified to be native. */
	var Promise = getNative(root, 'Promise');
	
	module.exports = Promise;


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

	var getNative = __webpack_require__(91),
	    root = __webpack_require__(96);
	
	/* Built-in method references that are verified to be native. */
	var Set = getNative(root, 'Set');
	
	module.exports = Set;


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

	var getNative = __webpack_require__(91),
	    root = __webpack_require__(96);
	
	/* Built-in method references that are verified to be native. */
	var WeakMap = getNative(root, 'WeakMap');
	
	module.exports = WeakMap;


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

	var baseGetTag = __webpack_require__(94),
	    getPrototype = __webpack_require__(164),
	    isObjectLike = __webpack_require__(143);
	
	/** `Object#toString` result references. */
	var objectTag = '[object Object]';
	
	/** Used for built-in method references. */
	var funcProto = Function.prototype,
	    objectProto = Object.prototype;
	
	/** Used to resolve the decompiled source of functions. */
	var funcToString = funcProto.toString;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/** Used to infer the `Object` constructor. */
	var objectCtorString = funcToString.call(Object);
	
	/**
	 * Checks if `value` is a plain object, that is, an object created by the
	 * `Object` constructor or one with a `[[Prototype]]` of `null`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.8.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
	 * @example
	 *
	 * function Foo() {
	 *   this.a = 1;
	 * }
	 *
	 * _.isPlainObject(new Foo);
	 * // => false
	 *
	 * _.isPlainObject([1, 2, 3]);
	 * // => false
	 *
	 * _.isPlainObject({ 'x': 0, 'y': 0 });
	 * // => true
	 *
	 * _.isPlainObject(Object.create(null));
	 * // => true
	 */
	function isPlainObject(value) {
	  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
	    return false;
	  }
	  var proto = getPrototype(value);
	  if (proto === null) {
	    return true;
	  }
	  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
	  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
	    funcToString.call(Ctor) == objectCtorString;
	}
	
	module.exports = isPlainObject;


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

	var overArg = __webpack_require__(156);
	
	/** Built-in value references. */
	var getPrototype = overArg(Object.getPrototypeOf, Object);
	
	module.exports = getPrototype;


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	exports.JUPYTER_WIDGETS_VERSION = '1.0.0';
	exports.PROTOCOL_VERSION = '2.0.0';


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils = __webpack_require__(4);
	var backbonePatch = __webpack_require__(167);
	var Backbone = __webpack_require__(168);
	var $ = __webpack_require__(170);
	var nativeview_1 = __webpack_require__(171);
	var widgets_1 = __webpack_require__(172);
	var messaging_1 = __webpack_require__(196);
	var version_1 = __webpack_require__(165);
	/**
	 * Replace model ids with models recursively.
	 */
	function unpack_models(value, manager) {
	    var unpacked;
	    if (Array.isArray(value)) {
	        unpacked = [];
	        value.forEach(function (sub_value, key) {
	            unpacked.push(unpack_models(sub_value, manager));
	        });
	        return Promise.all(unpacked);
	    }
	    else if (value instanceof Object) {
	        unpacked = {};
	        Object.keys(value).forEach(function (key) {
	            unpacked[key] = unpack_models(value[key], manager);
	        });
	        return utils.resolvePromisesDict(unpacked);
	    }
	    else if (typeof value === 'string' && value.slice(0, 10) === 'IPY_MODEL_') {
	        // get_model returns a promise already
	        return manager.get_model(value.slice(10, value.length));
	    }
	    else {
	        return Promise.resolve(value);
	    }
	}
	exports.unpack_models = unpack_models;
	var WidgetModel = /** @class */ (function (_super) {
	    __extends(WidgetModel, _super);
	    function WidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * The default attributes.
	     */
	    WidgetModel.prototype.defaults = function () {
	        return {
	            _model_module: '@jupyter-widgets/base',
	            _model_name: 'WidgetModel',
	            _model_module_version: version_1.JUPYTER_WIDGETS_VERSION,
	            _view_module: '@jupyter-widgets/base',
	            _view_name: null,
	            _view_module_version: version_1.JUPYTER_WIDGETS_VERSION,
	            _view_count: null,
	        };
	    };
	    /**
	     * Test to see if the model has been synced with the server.
	     *
	     * #### Notes
	     * As of backbone 1.1, backbone ignores `patch` if it thinks the
	     * model has never been pushed.
	     */
	    WidgetModel.prototype.isNew = function () {
	        return false;
	    };
	    /**
	     * Constructor
	     *
	     * Initializes a WidgetModel instance. Called by the Backbone constructor.
	     *
	     * Parameters
	     * ----------
	     * widget_manager : WidgetManager instance
	     * model_id : string
	     *      An ID unique to this model.
	     * comm : Comm instance (optional)
	     */
	    WidgetModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        // Attributes should be initialized here, since user initialization may depend on it
	        this.widget_manager = options.widget_manager;
	        this.model_id = options.model_id;
	        var comm = options.comm;
	        this.views = Object.create(null);
	        this.state_change = Promise.resolve();
	        this._closed = false;
	        this._state_lock = null;
	        this._msg_buffer = null;
	        this._msg_buffer_callbacks = null;
	        this._pending_msgs = 0;
	        // _buffered_state_diff must be created *after* the super.initialize
	        // call above. See the note in the set() method below.
	        this._buffered_state_diff = {};
	        if (comm) {
	            // Remember comm associated with the model.
	            this.comm = comm;
	            // Hook comm messages up to model.
	            comm.on_close(this._handle_comm_closed.bind(this));
	            comm.on_msg(this._handle_comm_msg.bind(this));
	            this.comm_live = true;
	        }
	        else {
	            this.comm_live = false;
	        }
	    };
	    Object.defineProperty(WidgetModel.prototype, "comm_live", {
	        get: function () {
	            return this._comm_live;
	        },
	        set: function (x) {
	            this._comm_live = x;
	            this.trigger('comm_live_update');
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Send a custom msg over the comm.
	     */
	    WidgetModel.prototype.send = function (content, callbacks, buffers) {
	        if (this.comm !== undefined) {
	            var data = { method: 'custom', content: content };
	            this.comm.send(data, callbacks, {}, buffers);
	        }
	    };
	    /**
	     * Close model
	     *
	     * @param comm_closed - true if the comm is already being closed. If false, the comm will be closed.
	     *
	     * @returns - a promise that is fulfilled when all the associated views have been removed.
	     */
	    WidgetModel.prototype.close = function (comm_closed) {
	        var _this = this;
	        if (comm_closed === void 0) { comm_closed = false; }
	        // can only be closed once.
	        if (this._closed) {
	            return;
	        }
	        this._closed = true;
	        if (this.comm && !comm_closed) {
	            this.comm.close();
	        }
	        this.stopListening();
	        this.trigger('destroy', this);
	        if (this.comm) {
	            delete this.comm;
	        }
	        // Delete all views of this model
	        var views = Object.keys(this.views).map(function (id) {
	            return _this.views[id].then(function (view) { return view.remove(); });
	        });
	        delete this.views;
	        return Promise.all(views).then(function () { return; });
	    };
	    /**
	     * Handle when a widget comm is closed.
	     */
	    WidgetModel.prototype._handle_comm_closed = function (msg) {
	        this.trigger('comm:close');
	        this.close(true);
	    };
	    /**
	     * Handle incoming comm msg.
	     */
	    WidgetModel.prototype._handle_comm_msg = function (msg) {
	        var _this = this;
	        var method = msg.content.data.method;
	        switch (method) {
	            case 'update':
	                this.state_change = this.state_change
	                    .then(function () {
	                    var state = msg.content.data.state;
	                    var buffer_paths = msg.content.data.buffer_paths || [];
	                    // Make sure the buffers are DataViews
	                    var buffers = (msg.buffers || []).map(function (b) {
	                        if (b instanceof DataView) {
	                            return b;
	                        }
	                        else {
	                            return new DataView(b instanceof ArrayBuffer ? b : b.buffer);
	                        }
	                    });
	                    utils.put_buffers(state, buffer_paths, buffers);
	                    return _this.constructor._deserialize_state(state, _this.widget_manager);
	                }).then(function (state) {
	                    _this.set_state(state);
	                }).catch(utils.reject("Could not process update msg for model id: " + this.model_id, true));
	                return this.state_change;
	            case 'custom':
	                this.trigger('msg:custom', msg.content.data.content, msg.buffers);
	                return Promise.resolve();
	        }
	    };
	    /**
	     * Handle when a widget is updated from the backend.
	     *
	     * This function is meant for internal use only. Values set here will not be propagated on a sync.
	     */
	    WidgetModel.prototype.set_state = function (state) {
	        this._state_lock = state;
	        try {
	            this.set(state);
	        }
	        catch (e) {
	            console.error("Error setting state: " + e.message);
	        }
	        finally {
	            this._state_lock = null;
	        }
	    };
	    /**
	     * Get the serializable state of the model.
	     *
	     * If drop_default is truthy, attributes that are equal to their default
	     * values are dropped.
	     */
	    WidgetModel.prototype.get_state = function (drop_defaults) {
	        var fullState = this.attributes;
	        if (drop_defaults) {
	            // if defaults is a function, call it
	            var d = this.defaults;
	            var defaults_1 = (typeof d === 'function') ? d.call(this) : d;
	            var state_1 = {};
	            Object.keys(fullState).forEach(function (key) {
	                if (!(utils.isEqual(fullState[key], defaults_1[key]))) {
	                    state_1[key] = fullState[key];
	                }
	            });
	            return state_1;
	        }
	        else {
	            return __assign({}, fullState);
	        }
	    };
	    /**
	     * Handle status msgs.
	     *
	     * execution_state : ('busy', 'idle', 'starting')
	     */
	    WidgetModel.prototype._handle_status = function (msg) {
	        if (this.comm !== void 0) {
	            if (msg.content.execution_state === 'idle') {
	                this._pending_msgs--;
	                // Send buffer if one is waiting and we are below the throttle.
	                if (this._msg_buffer !== null
	                    && this._pending_msgs < 1) {
	                    this.send_sync_message(this._msg_buffer, this._msg_buffer_callbacks);
	                    this._msg_buffer = null;
	                    this._msg_buffer_callbacks = null;
	                }
	            }
	        }
	    };
	    /**
	     * Create msg callbacks for a comm msg.
	     */
	    WidgetModel.prototype.callbacks = function (view) {
	        return this.widget_manager.callbacks(view);
	    };
	    /**
	     * Set one or more values.
	     *
	     * We just call the super method, in which val and options are optional.
	     * Handles both "key", value and {key: value} -style arguments.
	     */
	    WidgetModel.prototype.set = function (key, val, options) {
	        // Call our patched backbone set. See #1642 and #1643.
	        var return_value = backbonePatch.set.call(this, key, val, options);
	        // Backbone only remembers the diff of the most recent set()
	        // operation.  Calling set multiple times in a row results in a
	        // loss of change information.  Here we keep our own running diff.
	        //
	        // We don't buffer the state set in the constructor (including
	        // defaults), so we first check to see if we've initialized _buffered_state_diff.
	        // which happens after the constructor sets attributes at creation.
	        if (this._buffered_state_diff !== void 0) {
	            var attrs = this.changedAttributes() || {};
	            // The state_lock lists attributes that are currently being changed
	            // right now from a kernel message. We don't want to send these
	            // non-changes back to the kernel, so we delete them out of attrs if
	            // they haven't changed from their state_lock value.
	            // The state lock could be null or undefined (if set is being called from
	            // the initializer).
	            if (this._state_lock) {
	                for (var _i = 0, _a = Object.keys(this._state_lock); _i < _a.length; _i++) {
	                    var key_1 = _a[_i];
	                    if (attrs[key_1] === this._state_lock[key_1]) {
	                        delete attrs[key_1];
	                    }
	                }
	            }
	            this._buffered_state_diff = utils.assign(this._buffered_state_diff, attrs);
	        }
	        return return_value;
	    };
	    /**
	     * Handle sync to the back-end.  Called when a model.save() is called.
	     *
	     * Make sure a comm exists.
	     *
	     * Parameters
	     * ----------
	     * method : create, update, patch, delete, read
	     *   create/update always send the full attribute set
	     *   patch - only send attributes listed in options.attrs, and if we
	     *   are queuing up messages, combine with previous messages that have
	     *   not been sent yet
	     * model : the model we are syncing
	     *   will normally be the same as `this`
	     * options : dict
	     *   the `attrs` key, if it exists, gives an {attr: value} dict that
	     *   should be synced, otherwise, sync all attributes.
	     *
	     */
	    WidgetModel.prototype.sync = function (method, model, options) {
	        if (options === void 0) { options = {}; }
	        // the typing is to return `any` since the super.sync method returns a JqXHR, but we just return false if there is an error.
	        if (this.comm === undefined) {
	            throw 'Syncing error: no comm channel defined';
	        }
	        var attrs = (method === 'patch') ? options.attrs : model.get_state(options.drop_defaults);
	        // The state_lock lists attributes that are currently being changed
	        // right now from a kernel message. We don't want to send these
	        // non-changes back to the kernel, so we delete them out of attrs if
	        // they haven't changed from their state_lock value.
	        // The state lock could be null or undefined (if this is triggered
	        // from the initializer).
	        if (this._state_lock) {
	            for (var _i = 0, _a = Object.keys(this._state_lock); _i < _a.length; _i++) {
	                var key = _a[_i];
	                if (attrs[key] === this._state_lock[key]) {
	                    delete attrs[key];
	                }
	            }
	        }
	        var msgState = this.serialize(attrs);
	        if (Object.keys(msgState).length > 0) {
	            // If this message was sent via backbone itself, it will not
	            // have any callbacks.  It's important that we create callbacks
	            // so we can listen for status messages, etc...
	            var callbacks = options.callbacks || this.callbacks();
	            // Check throttle.
	            if (this._pending_msgs >= 1) {
	                // The throttle has been exceeded, buffer the current msg so
	                // it can be sent once the kernel has finished processing
	                // some of the existing messages.
	                // Combine updates if it is a 'patch' sync, otherwise replace updates
	                switch (method) {
	                    case 'patch':
	                        this._msg_buffer = utils.assign(this._msg_buffer || {}, msgState);
	                        break;
	                    case 'update':
	                    case 'create':
	                        this._msg_buffer = msgState;
	                        break;
	                    default:
	                        throw 'unrecognized syncing method';
	                }
	                this._msg_buffer_callbacks = callbacks;
	            }
	            else {
	                // We haven't exceeded the throttle, send the message like
	                // normal.
	                this.send_sync_message(attrs, callbacks);
	                // Since the comm is a one-way communication, assume the message
	                // arrived and was processed successfully.
	                // Don't call options.success since we don't have a model back from
	                // the server. Note that this means we don't have the Backbone
	                // 'sync' event.
	            }
	        }
	    };
	    /**
	     * Serialize widget state.
	     *
	     * A serializer is a function which takes in a state attribute and a widget,
	     * and synchronously returns a JSONable object. The returned object will
	     * have toJSON called if possible, and the final result should be a
	     * primitive object that is a snapshot of the widget state that may have
	     * binary array buffers.
	     */
	    WidgetModel.prototype.serialize = function (state) {
	        var serializers = this.constructor.serializers || {};
	        for (var _i = 0, _a = Object.keys(state); _i < _a.length; _i++) {
	            var k = _a[_i];
	            try {
	                if (serializers[k] && serializers[k].serialize) {
	                    state[k] = (serializers[k].serialize)(state[k], this);
	                }
	                else {
	                    // the default serializer just deep-copies the object
	                    state[k] = JSON.parse(JSON.stringify(state[k]));
	                }
	                if (state[k] && state[k].toJSON) {
	                    state[k] = state[k].toJSON();
	                }
	            }
	            catch (e) {
	                console.error('Error serializing widget state attribute: ', k);
	                throw e;
	            }
	        }
	        return state;
	    };
	    /**
	     * Send a sync message to the kernel.
	     */
	    WidgetModel.prototype.send_sync_message = function (state, callbacks) {
	        var _this = this;
	        if (callbacks === void 0) { callbacks = {}; }
	        try {
	            callbacks.iopub = callbacks.iopub || {};
	            var statuscb_1 = callbacks.iopub.status;
	            callbacks.iopub.status = function (msg) {
	                _this._handle_status(msg);
	                if (statuscb_1) {
	                    statuscb_1(msg);
	                }
	            };
	            // split out the binary buffers
	            var split = utils.remove_buffers(state);
	            this.comm.send({
	                method: 'update',
	                state: split.state,
	                buffer_paths: split.buffer_paths
	            }, callbacks, {}, split.buffers);
	            this._pending_msgs++;
	        }
	        catch (e) {
	            console.error('Could not send widget sync message', e);
	        }
	    };
	    /**
	     * Push this model's state to the back-end
	     *
	     * This invokes a Backbone.Sync.
	     */
	    WidgetModel.prototype.save_changes = function (callbacks) {
	        if (this.comm_live) {
	            var options = { patch: true };
	            if (callbacks) {
	                options.callbacks = callbacks;
	            }
	            this.save(this._buffered_state_diff, options);
	            this._buffered_state_diff = {};
	        }
	    };
	    /**
	     * on_some_change(['key1', 'key2'], foo, context) differs from
	     * on('change:key1 change:key2', foo, context).
	     * If the widget attributes key1 and key2 are both modified,
	     * the second form will result in foo being called twice
	     * while the first will call foo only once.
	     */
	    WidgetModel.prototype.on_some_change = function (keys, callback, context) {
	        this.on('change', function () {
	            if (keys.some(this.hasChanged, this)) {
	                callback.apply(context, arguments);
	            }
	        }, this);
	    };
	    /**
	     * Serialize the model.  See the deserialization function at the top of this file
	     * and the kernel-side serializer/deserializer.
	     */
	    WidgetModel.prototype.toJSON = function (options) {
	        return "IPY_MODEL_" + this.model_id;
	    };
	    /**
	     * Returns a promise for the deserialized state. The second argument
	     * is an instance of widget manager, which is required for the
	     * deserialization of widget models.
	     */
	    WidgetModel._deserialize_state = function (state, manager) {
	        var serializers = this.serializers;
	        var deserialized;
	        if (serializers) {
	            deserialized = {};
	            for (var k in state) {
	                if (serializers[k] && serializers[k].deserialize) {
	                    deserialized[k] = (serializers[k].deserialize)(state[k], manager);
	                }
	                else {
	                    deserialized[k] = state[k];
	                }
	            }
	        }
	        else {
	            deserialized = state;
	        }
	        return utils.resolvePromisesDict(deserialized);
	    };
	    return WidgetModel;
	}(Backbone.Model));
	exports.WidgetModel = WidgetModel;
	var DOMWidgetModel = /** @class */ (function (_super) {
	    __extends(DOMWidgetModel, _super);
	    function DOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DOMWidgetModel.prototype.defaults = function () {
	        return utils.assign(_super.prototype.defaults.call(this), {
	            _dom_classes: []
	            // We do not declare defaults for the layout and style attributes.
	            // Those defaults are constructed on the kernel side and synced here
	            // as needed, and our code here copes with those attributes being
	            // undefined. See
	            // https://github.com/jupyter-widgets/ipywidgets/issues/1620 and
	            // https://github.com/jupyter-widgets/ipywidgets/pull/1621
	        });
	    };
	    DOMWidgetModel.serializers = __assign({}, WidgetModel.serializers, { layout: { deserialize: unpack_models }, style: { deserialize: unpack_models } });
	    return DOMWidgetModel;
	}(WidgetModel));
	exports.DOMWidgetModel = DOMWidgetModel;
	var WidgetView = /** @class */ (function (_super) {
	    __extends(WidgetView, _super);
	    /**
	     * Public constructor.
	     */
	    function WidgetView(options) {
	        return _super.call(this, options) || this;
	    }
	    /**
	     * Initializer, called at the end of the constructor.
	     */
	    WidgetView.prototype.initialize = function (parameters) {
	        var _this = this;
	        this.listenTo(this.model, 'change', function () {
	            var changed = Object.keys(_this.model.changedAttributes() || {});
	            if (changed[0] === '_view_count' && changed.length === 1) {
	                // Just the view count was updated
	                return;
	            }
	            _this.update();
	        });
	        this.options = parameters.options;
	        this.once('remove', function () {
	            if (typeof (_this.model.get('_view_count')) === 'number') {
	                _this.model.set('_view_count', _this.model.get('_view_count') - 1);
	                _this.model.save_changes();
	            }
	        });
	        this.once('displayed', function () {
	            if (typeof (_this.model.get('_view_count')) === 'number') {
	                _this.model.set('_view_count', _this.model.get('_view_count') + 1);
	                _this.model.save_changes();
	            }
	        });
	        this.displayed = new Promise(function (resolve, reject) {
	            _this.once('displayed', resolve);
	        });
	    };
	    /**
	     * Triggered on model change.
	     *
	     * Update view to be consistent with this.model
	     */
	    WidgetView.prototype.update = function (options) {
	        return;
	    };
	    /**
	     * Render a view
	     *
	     * @returns the view or a promise to the view.
	     */
	    WidgetView.prototype.render = function () {
	        return;
	    };
	    /**
	     * Create and promise that resolves to a child view of a given model
	     */
	    WidgetView.prototype.create_child_view = function (child_model, options) {
	        if (options === void 0) { options = {}; }
	        var that = this;
	        options = __assign({ parent: this }, options);
	        return this.model.widget_manager.create_view(child_model, options)
	            .catch(utils.reject('Could not create child view', true));
	    };
	    /**
	     * Create msg callbacks for a comm msg.
	     */
	    WidgetView.prototype.callbacks = function () {
	        return this.model.callbacks(this);
	    };
	    /**
	     * Send a custom msg associated with this view.
	     */
	    WidgetView.prototype.send = function (content, buffers) {
	        this.model.send(content, this.callbacks(), buffers);
	    };
	    WidgetView.prototype.touch = function () {
	        this.model.save_changes(this.callbacks());
	    };
	    WidgetView.prototype.remove = function () {
	        // Raise a remove event when the view is removed.
	        _super.prototype.remove.call(this);
	        this.trigger('remove');
	        return this;
	    };
	    return WidgetView;
	}(nativeview_1.NativeView));
	exports.WidgetView = WidgetView;
	var JupyterPhosphorWidget = /** @class */ (function (_super) {
	    __extends(JupyterPhosphorWidget, _super);
	    function JupyterPhosphorWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        return _this;
	    }
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    /**
	     * Process the phosphor message.
	     *
	     * Any custom phosphor widget used inside a Jupyter widget should override
	     * the processMessage function like this.
	     */
	    JupyterPhosphorWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        this._view.processPhosphorMessage(msg);
	    };
	    return JupyterPhosphorWidget;
	}(widgets_1.Widget));
	exports.JupyterPhosphorWidget = JupyterPhosphorWidget;
	var DOMWidgetView = /** @class */ (function (_super) {
	    __extends(DOMWidgetView, _super);
	    function DOMWidgetView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    DOMWidgetView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.listenTo(this.model, 'change:_dom_classes', function (model, new_classes) {
	            var old_classes = model.previous('_dom_classes');
	            _this.update_classes(old_classes, new_classes);
	        });
	        this.layoutPromise = Promise.resolve();
	        this.listenTo(this.model, 'change:layout', function (model, value) {
	            _this.setLayout(value, model.previous('layout'));
	        });
	        this.stylePromise = Promise.resolve();
	        this.listenTo(this.model, 'change:style', function (model, value) {
	            _this.setStyle(value, model.previous('style'));
	        });
	        this.displayed.then(function () {
	            _this.update_classes([], _this.model.get('_dom_classes'));
	            _this.setLayout(_this.model.get('layout'));
	            _this.setStyle(_this.model.get('style'));
	        });
	        this._comm_live_update();
	        this.listenTo(this.model, 'comm_live_update', function () {
	            _this._comm_live_update();
	        });
	    };
	    DOMWidgetView.prototype.setLayout = function (layout, oldLayout) {
	        var _this = this;
	        if (layout) {
	            this.layoutPromise = this.layoutPromise.then(function (oldLayoutView) {
	                if (oldLayoutView) {
	                    oldLayoutView.unlayout();
	                    _this.stopListening(oldLayoutView.model);
	                    oldLayoutView.remove();
	                }
	                return _this.create_child_view(layout).then(function (view) {
	                    // Trigger the displayed event of the child view.
	                    return _this.displayed.then(function () {
	                        view.trigger('displayed');
	                        _this.listenTo(view.model, 'change', function () {
	                            // Post (asynchronous) so layout changes can take
	                            // effect first.
	                            messaging_1.MessageLoop.postMessage(_this.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	                        });
	                        messaging_1.MessageLoop.postMessage(_this.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	                        return view;
	                    });
	                }).catch(utils.reject('Could not add LayoutView to DOMWidgetView', true));
	            });
	        }
	    };
	    DOMWidgetView.prototype.setStyle = function (style, oldStyle) {
	        var _this = this;
	        if (style) {
	            this.stylePromise = this.stylePromise.then(function (oldStyleView) {
	                if (oldStyleView) {
	                    oldStyleView.unstyle();
	                    _this.stopListening(oldStyleView.model);
	                    oldStyleView.remove();
	                }
	                return _this.create_child_view(style).then(function (view) {
	                    // Trigger the displayed event of the child view.
	                    return _this.displayed.then(function () {
	                        view.trigger('displayed');
	                        // Unlike for the layout attribute, style changes don't
	                        // trigger phosphor resize messages.
	                        return view;
	                    });
	                }).catch(utils.reject('Could not add styleView to DOMWidgetView', true));
	            });
	        }
	    };
	    /**
	     * Update the DOM classes applied to an element, default to this.el.
	     */
	    DOMWidgetView.prototype.update_classes = function (old_classes, new_classes, el) {
	        if (el === undefined) {
	            el = this.el;
	        }
	        utils.difference(old_classes, new_classes).map(function (c) {
	            if (el.classList) {
	                el.classList.remove(c);
	            }
	            else {
	                el.setAttribute('class', el.getAttribute('class').replace(c, ''));
	            }
	        });
	        utils.difference(new_classes, old_classes).map(function (c) {
	            if (el.classList) {
	                el.classList.add(c);
	            }
	            else {
	                el.setAttribute('class', el.getAttribute('class').concat(' ', c));
	            }
	        });
	    };
	    /**
	     * Update the DOM classes applied to the widget based on a single
	     * trait's value.
	     *
	     * Given a trait value classes map, this function automatically
	     * handles applying the appropriate classes to the widget element
	     * and removing classes that are no longer valid.
	     *
	     * Parameters
	     * ----------
	     * class_map: dictionary
	     *  Dictionary of trait values to class lists.
	     *  Example:
	     *      {
	     *          success: ['alert', 'alert-success'],
	     *          info: ['alert', 'alert-info'],
	     *          warning: ['alert', 'alert-warning'],
	     *          danger: ['alert', 'alert-danger']
	     *      };
	     * trait_name: string
	     *  Name of the trait to check the value of.
	     * el: optional DOM element handle, defaults to this.el
	     *  Element that the classes are applied to.
	     */
	    DOMWidgetView.prototype.update_mapped_classes = function (class_map, trait_name, el) {
	        var key = this.model.previous(trait_name);
	        var old_classes = class_map[key] ? class_map[key] : [];
	        key = this.model.get(trait_name);
	        var new_classes = class_map[key] ? class_map[key] : [];
	        this.update_classes(old_classes, new_classes, el || this.el);
	    };
	    DOMWidgetView.prototype.set_mapped_classes = function (class_map, trait_name, el) {
	        var key = this.model.get(trait_name);
	        var new_classes = class_map[key] ? class_map[key] : [];
	        this.update_classes([], new_classes, el || this.el);
	    };
	    DOMWidgetView.prototype._setElement = function (el) {
	        if (this.pWidget) {
	            this.pWidget.dispose();
	        }
	        this.$el = el instanceof $ ? el : $(el);
	        this.el = this.$el[0];
	        this.pWidget = new JupyterPhosphorWidget({
	            node: el,
	            view: this
	        });
	    };
	    DOMWidgetView.prototype.remove = function () {
	        if (this.pWidget) {
	            this.pWidget.dispose();
	        }
	        return _super.prototype.remove.call(this);
	    };
	    DOMWidgetView.prototype.processPhosphorMessage = function (msg) {
	        switch (msg.type) {
	            case 'after-attach':
	                this.trigger('displayed');
	                break;
	        }
	    };
	    DOMWidgetView.prototype._comm_live_update = function () {
	        if (this.model.comm_live) {
	            this.pWidget.removeClass('jupyter-widgets-disconnected');
	        }
	        else {
	            this.pWidget.addClass('jupyter-widgets-disconnected');
	        }
	    };
	    return DOMWidgetView;
	}(WidgetView));
	exports.DOMWidgetView = DOMWidgetView;


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

	"use strict";
	// This file contains a modified version of the set function from the Backbone
	// (see
	// https://github.com/jashkenas/backbone/blob/05fde9e201f7e2137796663081105cd6dad12a98/backbone.js#L460,
	// with changes below marked with an EDIT comment). This file in Backbone has the following license.
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	//     (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	//     Backbone may be freely distributed under the MIT license.
	//     For all details and documentation:
	//     http://backbonejs.org
	// Backbone's full license is below (from https://github.com/jashkenas/backbone/blob/05fde9e201f7e2137796663081105cd6dad12a98/LICENSE)
	/*
	Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud
	
	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:
	
	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.
	
	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
	*/
	var utils = __webpack_require__(4);
	// Set a hash of model attributes on the object, firing `"change"`. This is
	// the core primitive operation of a model, updating the data and notifying
	// anyone who needs to know about the change in state. The heart of the beast.
	// This *MUST* be called with the model as the `this` context.
	function set(key, val, options) {
	    if (key == null) {
	        return this;
	    }
	    // Handle both `"key", value` and `{key: value}` -style arguments.
	    var attrs;
	    if (typeof key === 'object') {
	        attrs = key;
	        options = val;
	    }
	    else {
	        (attrs = {})[key] = val;
	    }
	    options || (options = {});
	    // Run validation.
	    if (!this._validate(attrs, options)) {
	        return false;
	    }
	    // Extract attributes and options.
	    var unset = options.unset;
	    var silent = options.silent;
	    var changes = [];
	    var changing = this._changing;
	    this._changing = true;
	    if (!changing) {
	        // EDIT: changed to use object spread instead of _.clone
	        this._previousAttributes = __assign({}, this.attributes);
	        this.changed = {};
	    }
	    var current = this.attributes;
	    var changed = this.changed;
	    var prev = this._previousAttributes;
	    // For each `set` attribute, update or delete the current value.
	    for (var attr in attrs) {
	        val = attrs[attr];
	        // EDIT: the following two lines use our isEqual instead of _.isEqual
	        if (!utils.isEqual(current[attr], val)) {
	            changes.push(attr);
	        }
	        if (!utils.isEqual(prev[attr], val)) {
	            changed[attr] = val;
	        }
	        else {
	            delete changed[attr];
	        }
	        unset ? delete current[attr] : current[attr] = val;
	    }
	    // Update the `id`.
	    this.id = this.get(this.idAttribute);
	    // Trigger all relevant attribute changes.
	    if (!silent) {
	        if (changes.length) {
	            this._pending = options;
	        }
	        for (var i = 0; i < changes.length; i++) {
	            this.trigger('change:' + changes[i], this, current[changes[i]], options);
	        }
	    }
	    // You might be wondering why there's a `while` loop here. Changes can
	    // be recursively nested within `"change"` events.
	    if (changing) {
	        return this;
	    }
	    if (!silent) {
	        while (this._pending) {
	            options = this._pending;
	            this._pending = false;
	            this.trigger('change', this, options);
	        }
	    }
	    this._pending = false;
	    this._changing = false;
	    return this;
	}
	exports.set = set;


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

	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global) {//     Backbone.js 1.2.3
	
	//     (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	//     Backbone may be freely distributed under the MIT license.
	//     For all details and documentation:
	//     http://backbonejs.org
	
	(function(factory) {
	
	  // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
	  // We use `self` instead of `window` for `WebWorker` support.
	  var root = (typeof self == 'object' && self.self == self && self) ||
	            (typeof global == 'object' && global.global == global && global);
	
	  // Set up Backbone appropriately for the environment. Start with AMD.
	  if (true) {
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(169), __webpack_require__(170), exports], __WEBPACK_AMD_DEFINE_RESULT__ = function(_, $, exports) {
	      // Export global even in AMD case in case this script is loaded with
	      // others that may still expect a global Backbone.
	      root.Backbone = factory(root, exports, _, $);
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	
	  // Next for Node.js or CommonJS. jQuery may not be needed as a module.
	  } else if (typeof exports !== 'undefined') {
	    var _ = require('underscore'), $;
	    try { $ = require('jquery'); } catch(e) {}
	    factory(root, exports, _, $);
	
	  // Finally, as a browser global.
	  } else {
	    root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
	  }
	
	}(function(root, Backbone, _, $) {
	
	  // Initial Setup
	  // -------------
	
	  // Save the previous value of the `Backbone` variable, so that it can be
	  // restored later on, if `noConflict` is used.
	  var previousBackbone = root.Backbone;
	
	  // Create a local reference to a common array method we'll want to use later.
	  var slice = Array.prototype.slice;
	
	  // Current version of the library. Keep in sync with `package.json`.
	  Backbone.VERSION = '1.2.3';
	
	  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
	  // the `$` variable.
	  Backbone.$ = $;
	
	  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
	  // to its previous owner. Returns a reference to this Backbone object.
	  Backbone.noConflict = function() {
	    root.Backbone = previousBackbone;
	    return this;
	  };
	
	  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
	  // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
	  // set a `X-Http-Method-Override` header.
	  Backbone.emulateHTTP = false;
	
	  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
	  // `application/json` requests ... this will encode the body as
	  // `application/x-www-form-urlencoded` instead and will send the model in a
	  // form param named `model`.
	  Backbone.emulateJSON = false;
	
	  // Proxy Backbone class methods to Underscore functions, wrapping the model's
	  // `attributes` object or collection's `models` array behind the scenes.
	  //
	  // collection.filter(function(model) { return model.get('age') > 10 });
	  // collection.each(this.addView);
	  //
	  // `Function#apply` can be slow so we use the method's arg count, if we know it.
	  var addMethod = function(length, method, attribute) {
	    switch (length) {
	      case 1: return function() {
	        return _[method](this[attribute]);
	      };
	      case 2: return function(value) {
	        return _[method](this[attribute], value);
	      };
	      case 3: return function(iteratee, context) {
	        return _[method](this[attribute], cb(iteratee, this), context);
	      };
	      case 4: return function(iteratee, defaultVal, context) {
	        return _[method](this[attribute], cb(iteratee, this), defaultVal, context);
	      };
	      default: return function() {
	        var args = slice.call(arguments);
	        args.unshift(this[attribute]);
	        return _[method].apply(_, args);
	      };
	    }
	  };
	  var addUnderscoreMethods = function(Class, methods, attribute) {
	    _.each(methods, function(length, method) {
	      if (_[method]) Class.prototype[method] = addMethod(length, method, attribute);
	    });
	  };
	
	  // Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.
	  var cb = function(iteratee, instance) {
	    if (_.isFunction(iteratee)) return iteratee;
	    if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
	    if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
	    return iteratee;
	  };
	  var modelMatcher = function(attrs) {
	    var matcher = _.matches(attrs);
	    return function(model) {
	      return matcher(model.attributes);
	    };
	  };
	
	  // Backbone.Events
	  // ---------------
	
	  // A module that can be mixed in to *any object* in order to provide it with
	  // a custom event channel. You may bind a callback to an event with `on` or
	  // remove with `off`; `trigger`-ing an event fires all callbacks in
	  // succession.
	  //
	  //     var object = {};
	  //     _.extend(object, Backbone.Events);
	  //     object.on('expand', function(){ alert('expanded'); });
	  //     object.trigger('expand');
	  //
	  var Events = Backbone.Events = {};
	
	  // Regular expression used to split event strings.
	  var eventSplitter = /\s+/;
	
	  // Iterates over the standard `event, callback` (as well as the fancy multiple
	  // space-separated events `"change blur", callback` and jQuery-style event
	  // maps `{event: callback}`).
	  var eventsApi = function(iteratee, events, name, callback, opts) {
	    var i = 0, names;
	    if (name && typeof name === 'object') {
	      // Handle event maps.
	      if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
	      for (names = _.keys(name); i < names.length ; i++) {
	        events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
	      }
	    } else if (name && eventSplitter.test(name)) {
	      // Handle space separated event names by delegating them individually.
	      for (names = name.split(eventSplitter); i < names.length; i++) {
	        events = iteratee(events, names[i], callback, opts);
	      }
	    } else {
	      // Finally, standard events.
	      events = iteratee(events, name, callback, opts);
	    }
	    return events;
	  };
	
	  // Bind an event to a `callback` function. Passing `"all"` will bind
	  // the callback to all events fired.
	  Events.on = function(name, callback, context) {
	    return internalOn(this, name, callback, context);
	  };
	
	  // Guard the `listening` argument from the public API.
	  var internalOn = function(obj, name, callback, context, listening) {
	    obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
	        context: context,
	        ctx: obj,
	        listening: listening
	    });
	
	    if (listening) {
	      var listeners = obj._listeners || (obj._listeners = {});
	      listeners[listening.id] = listening;
	    }
	
	    return obj;
	  };
	
	  // Inversion-of-control versions of `on`. Tell *this* object to listen to
	  // an event in another object... keeping track of what it's listening to
	  // for easier unbinding later.
	  Events.listenTo =  function(obj, name, callback) {
	    if (!obj) return this;
	    var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
	    var listeningTo = this._listeningTo || (this._listeningTo = {});
	    var listening = listeningTo[id];
	
	    // This object is not listening to any other events on `obj` yet.
	    // Setup the necessary references to track the listening callbacks.
	    if (!listening) {
	      var thisId = this._listenId || (this._listenId = _.uniqueId('l'));
	      listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0};
	    }
	
	    // Bind callbacks on obj, and keep track of them on listening.
	    internalOn(obj, name, callback, this, listening);
	    return this;
	  };
	
	  // The reducing API that adds a callback to the `events` object.
	  var onApi = function(events, name, callback, options) {
	    if (callback) {
	      var handlers = events[name] || (events[name] = []);
	      var context = options.context, ctx = options.ctx, listening = options.listening;
	      if (listening) listening.count++;
	
	      handlers.push({ callback: callback, context: context, ctx: context || ctx, listening: listening });
	    }
	    return events;
	  };
	
	  // Remove one or many callbacks. If `context` is null, removes all
	  // callbacks with that function. If `callback` is null, removes all
	  // callbacks for the event. If `name` is null, removes all bound
	  // callbacks for all events.
	  Events.off =  function(name, callback, context) {
	    if (!this._events) return this;
	    this._events = eventsApi(offApi, this._events, name, callback, {
	        context: context,
	        listeners: this._listeners
	    });
	    return this;
	  };
	
	  // Tell this object to stop listening to either specific events ... or
	  // to every object it's currently listening to.
	  Events.stopListening =  function(obj, name, callback) {
	    var listeningTo = this._listeningTo;
	    if (!listeningTo) return this;
	
	    var ids = obj ? [obj._listenId] : _.keys(listeningTo);
	
	    for (var i = 0; i < ids.length; i++) {
	      var listening = listeningTo[ids[i]];
	
	      // If listening doesn't exist, this object is not currently
	      // listening to obj. Break out early.
	      if (!listening) break;
	
	      listening.obj.off(name, callback, this);
	    }
	    if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
	
	    return this;
	  };
	
	  // The reducing API that removes a callback from the `events` object.
	  var offApi = function(events, name, callback, options) {
	    if (!events) return;
	
	    var i = 0, listening;
	    var context = options.context, listeners = options.listeners;
	
	    // Delete all events listeners and "drop" events.
	    if (!name && !callback && !context) {
	      var ids = _.keys(listeners);
	      for (; i < ids.length; i++) {
	        listening = listeners[ids[i]];
	        delete listeners[listening.id];
	        delete listening.listeningTo[listening.objId];
	      }
	      return;
	    }
	
	    var names = name ? [name] : _.keys(events);
	    for (; i < names.length; i++) {
	      name = names[i];
	      var handlers = events[name];
	
	      // Bail out if there are no events stored.
	      if (!handlers) break;
	
	      // Replace events if there are any remaining.  Otherwise, clean up.
	      var remaining = [];
	      for (var j = 0; j < handlers.length; j++) {
	        var handler = handlers[j];
	        if (
	          callback && callback !== handler.callback &&
	            callback !== handler.callback._callback ||
	              context && context !== handler.context
	        ) {
	          remaining.push(handler);
	        } else {
	          listening = handler.listening;
	          if (listening && --listening.count === 0) {
	            delete listeners[listening.id];
	            delete listening.listeningTo[listening.objId];
	          }
	        }
	      }
	
	      // Update tail event if the list has any events.  Otherwise, clean up.
	      if (remaining.length) {
	        events[name] = remaining;
	      } else {
	        delete events[name];
	      }
	    }
	    if (_.size(events)) return events;
	  };
	
	  // Bind an event to only be triggered a single time. After the first time
	  // the callback is invoked, its listener will be removed. If multiple events
	  // are passed in using the space-separated syntax, the handler will fire
	  // once for each event, not once for a combination of all events.
	  Events.once =  function(name, callback, context) {
	    // Map the event into a `{event: once}` object.
	    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
	    return this.on(events, void 0, context);
	  };
	
	  // Inversion-of-control versions of `once`.
	  Events.listenToOnce =  function(obj, name, callback) {
	    // Map the event into a `{event: once}` object.
	    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
	    return this.listenTo(obj, events);
	  };
	
	  // Reduces the event callbacks into a map of `{event: onceWrapper}`.
	  // `offer` unbinds the `onceWrapper` after it has been called.
	  var onceMap = function(map, name, callback, offer) {
	    if (callback) {
	      var once = map[name] = _.once(function() {
	        offer(name, once);
	        callback.apply(this, arguments);
	      });
	      once._callback = callback;
	    }
	    return map;
	  };
	
	  // Trigger one or many events, firing all bound callbacks. Callbacks are
	  // passed the same arguments as `trigger` is, apart from the event name
	  // (unless you're listening on `"all"`, which will cause your callback to
	  // receive the true name of the event as the first argument).
	  Events.trigger =  function(name) {
	    if (!this._events) return this;
	
	    var length = Math.max(0, arguments.length - 1);
	    var args = Array(length);
	    for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
	
	    eventsApi(triggerApi, this._events, name, void 0, args);
	    return this;
	  };
	
	  // Handles triggering the appropriate event callbacks.
	  var triggerApi = function(objEvents, name, cb, args) {
	    if (objEvents) {
	      var events = objEvents[name];
	      var allEvents = objEvents.all;
	      if (events && allEvents) allEvents = allEvents.slice();
	      if (events) triggerEvents(events, args);
	      if (allEvents) triggerEvents(allEvents, [name].concat(args));
	    }
	    return objEvents;
	  };
	
	  // A difficult-to-believe, but optimized internal dispatch function for
	  // triggering events. Tries to keep the usual cases speedy (most internal
	  // Backbone events have 3 arguments).
	  var triggerEvents = function(events, args) {
	    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
	    switch (args.length) {
	      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
	      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
	      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
	      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
	      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
	    }
	  };
	
	  // Aliases for backwards compatibility.
	  Events.bind   = Events.on;
	  Events.unbind = Events.off;
	
	  // Allow the `Backbone` object to serve as a global event bus, for folks who
	  // want global "pubsub" in a convenient place.
	  _.extend(Backbone, Events);
	
	  // Backbone.Model
	  // --------------
	
	  // Backbone **Models** are the basic data object in the framework --
	  // frequently representing a row in a table in a database on your server.
	  // A discrete chunk of data and a bunch of useful, related methods for
	  // performing computations and transformations on that data.
	
	  // Create a new model with the specified attributes. A client id (`cid`)
	  // is automatically generated and assigned for you.
	  var Model = Backbone.Model = function(attributes, options) {
	    var attrs = attributes || {};
	    options || (options = {});
	    this.cid = _.uniqueId(this.cidPrefix);
	    this.attributes = {};
	    if (options.collection) this.collection = options.collection;
	    if (options.parse) attrs = this.parse(attrs, options) || {};
	    attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
	    this.set(attrs, options);
	    this.changed = {};
	    this.initialize.apply(this, arguments);
	  };
	
	  // Attach all inheritable methods to the Model prototype.
	  _.extend(Model.prototype, Events, {
	
	    // A hash of attributes whose current and previous value differ.
	    changed: null,
	
	    // The value returned during the last failed validation.
	    validationError: null,
	
	    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
	    // CouchDB users may want to set this to `"_id"`.
	    idAttribute: 'id',
	
	    // The prefix is used to create the client id which is used to identify models locally.
	    // You may want to override this if you're experiencing name clashes with model ids.
	    cidPrefix: 'c',
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // Return a copy of the model's `attributes` object.
	    toJSON: function(options) {
	      return _.clone(this.attributes);
	    },
	
	    // Proxy `Backbone.sync` by default -- but override this if you need
	    // custom syncing semantics for *this* particular model.
	    sync: function() {
	      return Backbone.sync.apply(this, arguments);
	    },
	
	    // Get the value of an attribute.
	    get: function(attr) {
	      return this.attributes[attr];
	    },
	
	    // Get the HTML-escaped value of an attribute.
	    escape: function(attr) {
	      return _.escape(this.get(attr));
	    },
	
	    // Returns `true` if the attribute contains a value that is not null
	    // or undefined.
	    has: function(attr) {
	      return this.get(attr) != null;
	    },
	
	    // Special-cased proxy to underscore's `_.matches` method.
	    matches: function(attrs) {
	      return !!_.iteratee(attrs, this)(this.attributes);
	    },
	
	    // Set a hash of model attributes on the object, firing `"change"`. This is
	    // the core primitive operation of a model, updating the data and notifying
	    // anyone who needs to know about the change in state. The heart of the beast.
	    set: function(key, val, options) {
	      if (key == null) return this;
	
	      // Handle both `"key", value` and `{key: value}` -style arguments.
	      var attrs;
	      if (typeof key === 'object') {
	        attrs = key;
	        options = val;
	      } else {
	        (attrs = {})[key] = val;
	      }
	
	      options || (options = {});
	
	      // Run validation.
	      if (!this._validate(attrs, options)) return false;
	
	      // Extract attributes and options.
	      var unset      = options.unset;
	      var silent     = options.silent;
	      var changes    = [];
	      var changing   = this._changing;
	      this._changing = true;
	
	      if (!changing) {
	        this._previousAttributes = _.clone(this.attributes);
	        this.changed = {};
	      }
	
	      var current = this.attributes;
	      var changed = this.changed;
	      var prev    = this._previousAttributes;
	
	      // For each `set` attribute, update or delete the current value.
	      for (var attr in attrs) {
	        val = attrs[attr];
	        if (!_.isEqual(current[attr], val)) changes.push(attr);
	        if (!_.isEqual(prev[attr], val)) {
	          changed[attr] = val;
	        } else {
	          delete changed[attr];
	        }
	        unset ? delete current[attr] : current[attr] = val;
	      }
	
	      // Update the `id`.
	      this.id = this.get(this.idAttribute);
	
	      // Trigger all relevant attribute changes.
	      if (!silent) {
	        if (changes.length) this._pending = options;
	        for (var i = 0; i < changes.length; i++) {
	          this.trigger('change:' + changes[i], this, current[changes[i]], options);
	        }
	      }
	
	      // You might be wondering why there's a `while` loop here. Changes can
	      // be recursively nested within `"change"` events.
	      if (changing) return this;
	      if (!silent) {
	        while (this._pending) {
	          options = this._pending;
	          this._pending = false;
	          this.trigger('change', this, options);
	        }
	      }
	      this._pending = false;
	      this._changing = false;
	      return this;
	    },
	
	    // Remove an attribute from the model, firing `"change"`. `unset` is a noop
	    // if the attribute doesn't exist.
	    unset: function(attr, options) {
	      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
	    },
	
	    // Clear all attributes on the model, firing `"change"`.
	    clear: function(options) {
	      var attrs = {};
	      for (var key in this.attributes) attrs[key] = void 0;
	      return this.set(attrs, _.extend({}, options, {unset: true}));
	    },
	
	    // Determine if the model has changed since the last `"change"` event.
	    // If you specify an attribute name, determine if that attribute has changed.
	    hasChanged: function(attr) {
	      if (attr == null) return !_.isEmpty(this.changed);
	      return _.has(this.changed, attr);
	    },
	
	    // Return an object containing all the attributes that have changed, or
	    // false if there are no changed attributes. Useful for determining what
	    // parts of a view need to be updated and/or what attributes need to be
	    // persisted to the server. Unset attributes will be set to undefined.
	    // You can also pass an attributes object to diff against the model,
	    // determining if there *would be* a change.
	    changedAttributes: function(diff) {
	      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
	      var old = this._changing ? this._previousAttributes : this.attributes;
	      var changed = {};
	      for (var attr in diff) {
	        var val = diff[attr];
	        if (_.isEqual(old[attr], val)) continue;
	        changed[attr] = val;
	      }
	      return _.size(changed) ? changed : false;
	    },
	
	    // Get the previous value of an attribute, recorded at the time the last
	    // `"change"` event was fired.
	    previous: function(attr) {
	      if (attr == null || !this._previousAttributes) return null;
	      return this._previousAttributes[attr];
	    },
	
	    // Get all of the attributes of the model at the time of the previous
	    // `"change"` event.
	    previousAttributes: function() {
	      return _.clone(this._previousAttributes);
	    },
	
	    // Fetch the model from the server, merging the response with the model's
	    // local attributes. Any changed attributes will trigger a "change" event.
	    fetch: function(options) {
	      options = _.extend({parse: true}, options);
	      var model = this;
	      var success = options.success;
	      options.success = function(resp) {
	        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
	        if (!model.set(serverAttrs, options)) return false;
	        if (success) success.call(options.context, model, resp, options);
	        model.trigger('sync', model, resp, options);
	      };
	      wrapError(this, options);
	      return this.sync('read', this, options);
	    },
	
	    // Set a hash of model attributes, and sync the model to the server.
	    // If the server returns an attributes hash that differs, the model's
	    // state will be `set` again.
	    save: function(key, val, options) {
	      // Handle both `"key", value` and `{key: value}` -style arguments.
	      var attrs;
	      if (key == null || typeof key === 'object') {
	        attrs = key;
	        options = val;
	      } else {
	        (attrs = {})[key] = val;
	      }
	
	      options = _.extend({validate: true, parse: true}, options);
	      var wait = options.wait;
	
	      // If we're not waiting and attributes exist, save acts as
	      // `set(attr).save(null, opts)` with validation. Otherwise, check if
	      // the model will be valid when the attributes, if any, are set.
	      if (attrs && !wait) {
	        if (!this.set(attrs, options)) return false;
	      } else {
	        if (!this._validate(attrs, options)) return false;
	      }
	
	      // After a successful server-side save, the client is (optionally)
	      // updated with the server-side state.
	      var model = this;
	      var success = options.success;
	      var attributes = this.attributes;
	      options.success = function(resp) {
	        // Ensure attributes are restored during synchronous saves.
	        model.attributes = attributes;
	        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
	        if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
	        if (serverAttrs && !model.set(serverAttrs, options)) return false;
	        if (success) success.call(options.context, model, resp, options);
	        model.trigger('sync', model, resp, options);
	      };
	      wrapError(this, options);
	
	      // Set temporary attributes if `{wait: true}` to properly find new ids.
	      if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
	
	      var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
	      if (method === 'patch' && !options.attrs) options.attrs = attrs;
	      var xhr = this.sync(method, this, options);
	
	      // Restore attributes.
	      this.attributes = attributes;
	
	      return xhr;
	    },
	
	    // Destroy this model on the server if it was already persisted.
	    // Optimistically removes the model from its collection, if it has one.
	    // If `wait: true` is passed, waits for the server to respond before removal.
	    destroy: function(options) {
	      options = options ? _.clone(options) : {};
	      var model = this;
	      var success = options.success;
	      var wait = options.wait;
	
	      var destroy = function() {
	        model.stopListening();
	        model.trigger('destroy', model, model.collection, options);
	      };
	
	      options.success = function(resp) {
	        if (wait) destroy();
	        if (success) success.call(options.context, model, resp, options);
	        if (!model.isNew()) model.trigger('sync', model, resp, options);
	      };
	
	      var xhr = false;
	      if (this.isNew()) {
	        _.defer(options.success);
	      } else {
	        wrapError(this, options);
	        xhr = this.sync('delete', this, options);
	      }
	      if (!wait) destroy();
	      return xhr;
	    },
	
	    // Default URL for the model's representation on the server -- if you're
	    // using Backbone's restful methods, override this to change the endpoint
	    // that will be called.
	    url: function() {
	      var base =
	        _.result(this, 'urlRoot') ||
	        _.result(this.collection, 'url') ||
	        urlError();
	      if (this.isNew()) return base;
	      var id = this.get(this.idAttribute);
	      return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
	    },
	
	    // **parse** converts a response into the hash of attributes to be `set` on
	    // the model. The default implementation is just to pass the response along.
	    parse: function(resp, options) {
	      return resp;
	    },
	
	    // Create a new model with identical attributes to this one.
	    clone: function() {
	      return new this.constructor(this.attributes);
	    },
	
	    // A model is new if it has never been saved to the server, and lacks an id.
	    isNew: function() {
	      return !this.has(this.idAttribute);
	    },
	
	    // Check if the model is currently in a valid state.
	    isValid: function(options) {
	      return this._validate({}, _.defaults({validate: true}, options));
	    },
	
	    // Run validation against the next complete set of model attributes,
	    // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
	    _validate: function(attrs, options) {
	      if (!options.validate || !this.validate) return true;
	      attrs = _.extend({}, this.attributes, attrs);
	      var error = this.validationError = this.validate(attrs, options) || null;
	      if (!error) return true;
	      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
	      return false;
	    }
	
	  });
	
	  // Underscore methods that we want to implement on the Model, mapped to the
	  // number of arguments they take.
	  var modelMethods = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
	      omit: 0, chain: 1, isEmpty: 1 };
	
	  // Mix in each Underscore method as a proxy to `Model#attributes`.
	  addUnderscoreMethods(Model, modelMethods, 'attributes');
	
	  // Backbone.Collection
	  // -------------------
	
	  // If models tend to represent a single row of data, a Backbone Collection is
	  // more analogous to a table full of data ... or a small slice or page of that
	  // table, or a collection of rows that belong together for a particular reason
	  // -- all of the messages in this particular folder, all of the documents
	  // belonging to this particular author, and so on. Collections maintain
	  // indexes of their models, both in order, and for lookup by `id`.
	
	  // Create a new **Collection**, perhaps to contain a specific type of `model`.
	  // If a `comparator` is specified, the Collection will maintain
	  // its models in sort order, as they're added and removed.
	  var Collection = Backbone.Collection = function(models, options) {
	    options || (options = {});
	    if (options.model) this.model = options.model;
	    if (options.comparator !== void 0) this.comparator = options.comparator;
	    this._reset();
	    this.initialize.apply(this, arguments);
	    if (models) this.reset(models, _.extend({silent: true}, options));
	  };
	
	  // Default options for `Collection#set`.
	  var setOptions = {add: true, remove: true, merge: true};
	  var addOptions = {add: true, remove: false};
	
	  // Splices `insert` into `array` at index `at`.
	  var splice = function(array, insert, at) {
	    at = Math.min(Math.max(at, 0), array.length);
	    var tail = Array(array.length - at);
	    var length = insert.length;
	    for (var i = 0; i < tail.length; i++) tail[i] = array[i + at];
	    for (i = 0; i < length; i++) array[i + at] = insert[i];
	    for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
	  };
	
	  // Define the Collection's inheritable methods.
	  _.extend(Collection.prototype, Events, {
	
	    // The default model for a collection is just a **Backbone.Model**.
	    // This should be overridden in most cases.
	    model: Model,
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // The JSON representation of a Collection is an array of the
	    // models' attributes.
	    toJSON: function(options) {
	      return this.map(function(model) { return model.toJSON(options); });
	    },
	
	    // Proxy `Backbone.sync` by default.
	    sync: function() {
	      return Backbone.sync.apply(this, arguments);
	    },
	
	    // Add a model, or list of models to the set. `models` may be Backbone
	    // Models or raw JavaScript objects to be converted to Models, or any
	    // combination of the two.
	    add: function(models, options) {
	      return this.set(models, _.extend({merge: false}, options, addOptions));
	    },
	
	    // Remove a model, or a list of models from the set.
	    remove: function(models, options) {
	      options = _.extend({}, options);
	      var singular = !_.isArray(models);
	      models = singular ? [models] : _.clone(models);
	      var removed = this._removeModels(models, options);
	      if (!options.silent && removed) this.trigger('update', this, options);
	      return singular ? removed[0] : removed;
	    },
	
	    // Update a collection by `set`-ing a new list of models, adding new ones,
	    // removing models that are no longer present, and merging models that
	    // already exist in the collection, as necessary. Similar to **Model#set**,
	    // the core operation for updating the data contained by the collection.
	    set: function(models, options) {
	      if (models == null) return;
	
	      options = _.defaults({}, options, setOptions);
	      if (options.parse && !this._isModel(models)) models = this.parse(models, options);
	
	      var singular = !_.isArray(models);
	      models = singular ? [models] : models.slice();
	
	      var at = options.at;
	      if (at != null) at = +at;
	      if (at < 0) at += this.length + 1;
	
	      var set = [];
	      var toAdd = [];
	      var toRemove = [];
	      var modelMap = {};
	
	      var add = options.add;
	      var merge = options.merge;
	      var remove = options.remove;
	
	      var sort = false;
	      var sortable = this.comparator && (at == null) && options.sort !== false;
	      var sortAttr = _.isString(this.comparator) ? this.comparator : null;
	
	      // Turn bare objects into model references, and prevent invalid models
	      // from being added.
	      var model;
	      for (var i = 0; i < models.length; i++) {
	        model = models[i];
	
	        // If a duplicate is found, prevent it from being added and
	        // optionally merge it into the existing model.
	        var existing = this.get(model);
	        if (existing) {
	          if (merge && model !== existing) {
	            var attrs = this._isModel(model) ? model.attributes : model;
	            if (options.parse) attrs = existing.parse(attrs, options);
	            existing.set(attrs, options);
	            if (sortable && !sort) sort = existing.hasChanged(sortAttr);
	          }
	          if (!modelMap[existing.cid]) {
	            modelMap[existing.cid] = true;
	            set.push(existing);
	          }
	          models[i] = existing;
	
	        // If this is a new, valid model, push it to the `toAdd` list.
	        } else if (add) {
	          model = models[i] = this._prepareModel(model, options);
	          if (model) {
	            toAdd.push(model);
	            this._addReference(model, options);
	            modelMap[model.cid] = true;
	            set.push(model);
	          }
	        }
	      }
	
	      // Remove stale models.
	      if (remove) {
	        for (i = 0; i < this.length; i++) {
	          model = this.models[i];
	          if (!modelMap[model.cid]) toRemove.push(model);
	        }
	        if (toRemove.length) this._removeModels(toRemove, options);
	      }
	
	      // See if sorting is needed, update `length` and splice in new models.
	      var orderChanged = false;
	      var replace = !sortable && add && remove;
	      if (set.length && replace) {
	        orderChanged = this.length != set.length || _.some(this.models, function(model, index) {
	          return model !== set[index];
	        });
	        this.models.length = 0;
	        splice(this.models, set, 0);
	        this.length = this.models.length;
	      } else if (toAdd.length) {
	        if (sortable) sort = true;
	        splice(this.models, toAdd, at == null ? this.length : at);
	        this.length = this.models.length;
	      }
	
	      // Silently sort the collection if appropriate.
	      if (sort) this.sort({silent: true});
	
	      // Unless silenced, it's time to fire all appropriate add/sort events.
	      if (!options.silent) {
	        for (i = 0; i < toAdd.length; i++) {
	          if (at != null) options.index = at + i;
	          model = toAdd[i];
	          model.trigger('add', model, this, options);
	        }
	        if (sort || orderChanged) this.trigger('sort', this, options);
	        if (toAdd.length || toRemove.length) this.trigger('update', this, options);
	      }
	
	      // Return the added (or merged) model (or models).
	      return singular ? models[0] : models;
	    },
	
	    // When you have more items than you want to add or remove individually,
	    // you can reset the entire set with a new list of models, without firing
	    // any granular `add` or `remove` events. Fires `reset` when finished.
	    // Useful for bulk operations and optimizations.
	    reset: function(models, options) {
	      options = options ? _.clone(options) : {};
	      for (var i = 0; i < this.models.length; i++) {
	        this._removeReference(this.models[i], options);
	      }
	      options.previousModels = this.models;
	      this._reset();
	      models = this.add(models, _.extend({silent: true}, options));
	      if (!options.silent) this.trigger('reset', this, options);
	      return models;
	    },
	
	    // Add a model to the end of the collection.
	    push: function(model, options) {
	      return this.add(model, _.extend({at: this.length}, options));
	    },
	
	    // Remove a model from the end of the collection.
	    pop: function(options) {
	      var model = this.at(this.length - 1);
	      return this.remove(model, options);
	    },
	
	    // Add a model to the beginning of the collection.
	    unshift: function(model, options) {
	      return this.add(model, _.extend({at: 0}, options));
	    },
	
	    // Remove a model from the beginning of the collection.
	    shift: function(options) {
	      var model = this.at(0);
	      return this.remove(model, options);
	    },
	
	    // Slice out a sub-array of models from the collection.
	    slice: function() {
	      return slice.apply(this.models, arguments);
	    },
	
	    // Get a model from the set by id.
	    get: function(obj) {
	      if (obj == null) return void 0;
	      var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
	      return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
	    },
	
	    // Get the model at the given index.
	    at: function(index) {
	      if (index < 0) index += this.length;
	      return this.models[index];
	    },
	
	    // Return models with matching attributes. Useful for simple cases of
	    // `filter`.
	    where: function(attrs, first) {
	      return this[first ? 'find' : 'filter'](attrs);
	    },
	
	    // Return the first model with matching attributes. Useful for simple cases
	    // of `find`.
	    findWhere: function(attrs) {
	      return this.where(attrs, true);
	    },
	
	    // Force the collection to re-sort itself. You don't need to call this under
	    // normal circumstances, as the set will maintain sort order as each item
	    // is added.
	    sort: function(options) {
	      var comparator = this.comparator;
	      if (!comparator) throw new Error('Cannot sort a set without a comparator');
	      options || (options = {});
	
	      var length = comparator.length;
	      if (_.isFunction(comparator)) comparator = _.bind(comparator, this);
	
	      // Run sort based on type of `comparator`.
	      if (length === 1 || _.isString(comparator)) {
	        this.models = this.sortBy(comparator);
	      } else {
	        this.models.sort(comparator);
	      }
	      if (!options.silent) this.trigger('sort', this, options);
	      return this;
	    },
	
	    // Pluck an attribute from each model in the collection.
	    pluck: function(attr) {
	      return _.invoke(this.models, 'get', attr);
	    },
	
	    // Fetch the default set of models for this collection, resetting the
	    // collection when they arrive. If `reset: true` is passed, the response
	    // data will be passed through the `reset` method instead of `set`.
	    fetch: function(options) {
	      options = _.extend({parse: true}, options);
	      var success = options.success;
	      var collection = this;
	      options.success = function(resp) {
	        var method = options.reset ? 'reset' : 'set';
	        collection[method](resp, options);
	        if (success) success.call(options.context, collection, resp, options);
	        collection.trigger('sync', collection, resp, options);
	      };
	      wrapError(this, options);
	      return this.sync('read', this, options);
	    },
	
	    // Create a new instance of a model in this collection. Add the model to the
	    // collection immediately, unless `wait: true` is passed, in which case we
	    // wait for the server to agree.
	    create: function(model, options) {
	      options = options ? _.clone(options) : {};
	      var wait = options.wait;
	      model = this._prepareModel(model, options);
	      if (!model) return false;
	      if (!wait) this.add(model, options);
	      var collection = this;
	      var success = options.success;
	      options.success = function(model, resp, callbackOpts) {
	        if (wait) collection.add(model, callbackOpts);
	        if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
	      };
	      model.save(null, options);
	      return model;
	    },
	
	    // **parse** converts a response into a list of models to be added to the
	    // collection. The default implementation is just to pass it through.
	    parse: function(resp, options) {
	      return resp;
	    },
	
	    // Create a new collection with an identical list of models as this one.
	    clone: function() {
	      return new this.constructor(this.models, {
	        model: this.model,
	        comparator: this.comparator
	      });
	    },
	
	    // Define how to uniquely identify models in the collection.
	    modelId: function (attrs) {
	      return attrs[this.model.prototype.idAttribute || 'id'];
	    },
	
	    // Private method to reset all internal state. Called when the collection
	    // is first initialized or reset.
	    _reset: function() {
	      this.length = 0;
	      this.models = [];
	      this._byId  = {};
	    },
	
	    // Prepare a hash of attributes (or other model) to be added to this
	    // collection.
	    _prepareModel: function(attrs, options) {
	      if (this._isModel(attrs)) {
	        if (!attrs.collection) attrs.collection = this;
	        return attrs;
	      }
	      options = options ? _.clone(options) : {};
	      options.collection = this;
	      var model = new this.model(attrs, options);
	      if (!model.validationError) return model;
	      this.trigger('invalid', this, model.validationError, options);
	      return false;
	    },
	
	    // Internal method called by both remove and set.
	    _removeModels: function(models, options) {
	      var removed = [];
	      for (var i = 0; i < models.length; i++) {
	        var model = this.get(models[i]);
	        if (!model) continue;
	
	        var index = this.indexOf(model);
	        this.models.splice(index, 1);
	        this.length--;
	
	        if (!options.silent) {
	          options.index = index;
	          model.trigger('remove', model, this, options);
	        }
	
	        removed.push(model);
	        this._removeReference(model, options);
	      }
	      return removed.length ? removed : false;
	    },
	
	    // Method for checking whether an object should be considered a model for
	    // the purposes of adding to the collection.
	    _isModel: function (model) {
	      return model instanceof Model;
	    },
	
	    // Internal method to create a model's ties to a collection.
	    _addReference: function(model, options) {
	      this._byId[model.cid] = model;
	      var id = this.modelId(model.attributes);
	      if (id != null) this._byId[id] = model;
	      model.on('all', this._onModelEvent, this);
	    },
	
	    // Internal method to sever a model's ties to a collection.
	    _removeReference: function(model, options) {
	      delete this._byId[model.cid];
	      var id = this.modelId(model.attributes);
	      if (id != null) delete this._byId[id];
	      if (this === model.collection) delete model.collection;
	      model.off('all', this._onModelEvent, this);
	    },
	
	    // Internal method called every time a model in the set fires an event.
	    // Sets need to update their indexes when models change ids. All other
	    // events simply proxy through. "add" and "remove" events that originate
	    // in other collections are ignored.
	    _onModelEvent: function(event, model, collection, options) {
	      if ((event === 'add' || event === 'remove') && collection !== this) return;
	      if (event === 'destroy') this.remove(model, options);
	      if (event === 'change') {
	        var prevId = this.modelId(model.previousAttributes());
	        var id = this.modelId(model.attributes);
	        if (prevId !== id) {
	          if (prevId != null) delete this._byId[prevId];
	          if (id != null) this._byId[id] = model;
	        }
	      }
	      this.trigger.apply(this, arguments);
	    }
	
	  });
	
	  // Underscore methods that we want to implement on the Collection.
	  // 90% of the core usefulness of Backbone Collections is actually implemented
	  // right here:
	  var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
	      foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
	      select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
	      contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
	      head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
	      without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
	      isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
	      sortBy: 3, indexBy: 3};
	
	  // Mix in each Underscore method as a proxy to `Collection#models`.
	  addUnderscoreMethods(Collection, collectionMethods, 'models');
	
	  // Backbone.View
	  // -------------
	
	  // Backbone Views are almost more convention than they are actual code. A View
	  // is simply a JavaScript object that represents a logical chunk of UI in the
	  // DOM. This might be a single item, an entire list, a sidebar or panel, or
	  // even the surrounding frame which wraps your whole app. Defining a chunk of
	  // UI as a **View** allows you to define your DOM events declaratively, without
	  // having to worry about render order ... and makes it easy for the view to
	  // react to specific changes in the state of your models.
	
	  // Creating a Backbone.View creates its initial element outside of the DOM,
	  // if an existing element is not provided...
	  var View = Backbone.View = function(options) {
	    this.cid = _.uniqueId('view');
	    _.extend(this, _.pick(options, viewOptions));
	    this._ensureElement();
	    this.initialize.apply(this, arguments);
	  };
	
	  // Cached regex to split keys for `delegate`.
	  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
	
	  // List of view options to be set as properties.
	  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
	
	  // Set up all inheritable **Backbone.View** properties and methods.
	  _.extend(View.prototype, Events, {
	
	    // The default `tagName` of a View's element is `"div"`.
	    tagName: 'div',
	
	    // jQuery delegate for element lookup, scoped to DOM elements within the
	    // current view. This should be preferred to global lookups where possible.
	    $: function(selector) {
	      return this.$el.find(selector);
	    },
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // **render** is the core function that your view should override, in order
	    // to populate its element (`this.el`), with the appropriate HTML. The
	    // convention is for **render** to always return `this`.
	    render: function() {
	      return this;
	    },
	
	    // Remove this view by taking the element out of the DOM, and removing any
	    // applicable Backbone.Events listeners.
	    remove: function() {
	      this._removeElement();
	      this.stopListening();
	      return this;
	    },
	
	    // Remove this view's element from the document and all event listeners
	    // attached to it. Exposed for subclasses using an alternative DOM
	    // manipulation API.
	    _removeElement: function() {
	      this.$el.remove();
	    },
	
	    // Change the view's element (`this.el` property) and re-delegate the
	    // view's events on the new element.
	    setElement: function(element) {
	      this.undelegateEvents();
	      this._setElement(element);
	      this.delegateEvents();
	      return this;
	    },
	
	    // Creates the `this.el` and `this.$el` references for this view using the
	    // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
	    // context or an element. Subclasses can override this to utilize an
	    // alternative DOM manipulation API and are only required to set the
	    // `this.el` property.
	    _setElement: function(el) {
	      this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
	      this.el = this.$el[0];
	    },
	
	    // Set callbacks, where `this.events` is a hash of
	    //
	    // *{"event selector": "callback"}*
	    //
	    //     {
	    //       'mousedown .title':  'edit',
	    //       'click .button':     'save',
	    //       'click .open':       function(e) { ... }
	    //     }
	    //
	    // pairs. Callbacks will be bound to the view, with `this` set properly.
	    // Uses event delegation for efficiency.
	    // Omitting the selector binds the event to `this.el`.
	    delegateEvents: function(events) {
	      events || (events = _.result(this, 'events'));
	      if (!events) return this;
	      this.undelegateEvents();
	      for (var key in events) {
	        var method = events[key];
	        if (!_.isFunction(method)) method = this[method];
	        if (!method) continue;
	        var match = key.match(delegateEventSplitter);
	        this.delegate(match[1], match[2], _.bind(method, this));
	      }
	      return this;
	    },
	
	    // Add a single event listener to the view's element (or a child element
	    // using `selector`). This only works for delegate-able events: not `focus`,
	    // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
	    delegate: function(eventName, selector, listener) {
	      this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
	      return this;
	    },
	
	    // Clears all callbacks previously bound to the view by `delegateEvents`.
	    // You usually don't need to use this, but may wish to if you have multiple
	    // Backbone views attached to the same DOM element.
	    undelegateEvents: function() {
	      if (this.$el) this.$el.off('.delegateEvents' + this.cid);
	      return this;
	    },
	
	    // A finer-grained `undelegateEvents` for removing a single delegated event.
	    // `selector` and `listener` are both optional.
	    undelegate: function(eventName, selector, listener) {
	      this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
	      return this;
	    },
	
	    // Produces a DOM element to be assigned to your view. Exposed for
	    // subclasses using an alternative DOM manipulation API.
	    _createElement: function(tagName) {
	      return document.createElement(tagName);
	    },
	
	    // Ensure that the View has a DOM element to render into.
	    // If `this.el` is a string, pass it through `$()`, take the first
	    // matching element, and re-assign it to `el`. Otherwise, create
	    // an element from the `id`, `className` and `tagName` properties.
	    _ensureElement: function() {
	      if (!this.el) {
	        var attrs = _.extend({}, _.result(this, 'attributes'));
	        if (this.id) attrs.id = _.result(this, 'id');
	        if (this.className) attrs['class'] = _.result(this, 'className');
	        this.setElement(this._createElement(_.result(this, 'tagName')));
	        this._setAttributes(attrs);
	      } else {
	        this.setElement(_.result(this, 'el'));
	      }
	    },
	
	    // Set attributes from a hash on this view's element.  Exposed for
	    // subclasses using an alternative DOM manipulation API.
	    _setAttributes: function(attributes) {
	      this.$el.attr(attributes);
	    }
	
	  });
	
	  // Backbone.sync
	  // -------------
	
	  // Override this function to change the manner in which Backbone persists
	  // models to the server. You will be passed the type of request, and the
	  // model in question. By default, makes a RESTful Ajax request
	  // to the model's `url()`. Some possible customizations could be:
	  //
	  // * Use `setTimeout` to batch rapid-fire updates into a single request.
	  // * Send up the models as XML instead of JSON.
	  // * Persist models via WebSockets instead of Ajax.
	  //
	  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
	  // as `POST`, with a `_method` parameter containing the true HTTP method,
	  // as well as all requests with the body as `application/x-www-form-urlencoded`
	  // instead of `application/json` with the model in a param named `model`.
	  // Useful when interfacing with server-side languages like **PHP** that make
	  // it difficult to read the body of `PUT` requests.
	  Backbone.sync = function(method, model, options) {
	    var type = methodMap[method];
	
	    // Default options, unless specified.
	    _.defaults(options || (options = {}), {
	      emulateHTTP: Backbone.emulateHTTP,
	      emulateJSON: Backbone.emulateJSON
	    });
	
	    // Default JSON-request options.
	    var params = {type: type, dataType: 'json'};
	
	    // Ensure that we have a URL.
	    if (!options.url) {
	      params.url = _.result(model, 'url') || urlError();
	    }
	
	    // Ensure that we have the appropriate request data.
	    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
	      params.contentType = 'application/json';
	      params.data = JSON.stringify(options.attrs || model.toJSON(options));
	    }
	
	    // For older servers, emulate JSON by encoding the request into an HTML-form.
	    if (options.emulateJSON) {
	      params.contentType = 'application/x-www-form-urlencoded';
	      params.data = params.data ? {model: params.data} : {};
	    }
	
	    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
	    // And an `X-HTTP-Method-Override` header.
	    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
	      params.type = 'POST';
	      if (options.emulateJSON) params.data._method = type;
	      var beforeSend = options.beforeSend;
	      options.beforeSend = function(xhr) {
	        xhr.setRequestHeader('X-HTTP-Method-Override', type);
	        if (beforeSend) return beforeSend.apply(this, arguments);
	      };
	    }
	
	    // Don't process data on a non-GET request.
	    if (params.type !== 'GET' && !options.emulateJSON) {
	      params.processData = false;
	    }
	
	    // Pass along `textStatus` and `errorThrown` from jQuery.
	    var error = options.error;
	    options.error = function(xhr, textStatus, errorThrown) {
	      options.textStatus = textStatus;
	      options.errorThrown = errorThrown;
	      if (error) error.call(options.context, xhr, textStatus, errorThrown);
	    };
	
	    // Make the request, allowing the user to override any Ajax options.
	    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
	    model.trigger('request', model, xhr, options);
	    return xhr;
	  };
	
	  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
	  var methodMap = {
	    'create': 'POST',
	    'update': 'PUT',
	    'patch':  'PATCH',
	    'delete': 'DELETE',
	    'read':   'GET'
	  };
	
	  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
	  // Override this if you'd like to use a different library.
	  Backbone.ajax = function() {
	    return Backbone.$.ajax.apply(Backbone.$, arguments);
	  };
	
	  // Backbone.Router
	  // ---------------
	
	  // Routers map faux-URLs to actions, and fire events when routes are
	  // matched. Creating a new one sets its `routes` hash, if not set statically.
	  var Router = Backbone.Router = function(options) {
	    options || (options = {});
	    if (options.routes) this.routes = options.routes;
	    this._bindRoutes();
	    this.initialize.apply(this, arguments);
	  };
	
	  // Cached regular expressions for matching named param parts and splatted
	  // parts of route strings.
	  var optionalParam = /\((.*?)\)/g;
	  var namedParam    = /(\(\?)?:\w+/g;
	  var splatParam    = /\*\w+/g;
	  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
	
	  // Set up all inheritable **Backbone.Router** properties and methods.
	  _.extend(Router.prototype, Events, {
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // Manually bind a single named route to a callback. For example:
	    //
	    //     this.route('search/:query/p:num', 'search', function(query, num) {
	    //       ...
	    //     });
	    //
	    route: function(route, name, callback) {
	      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
	      if (_.isFunction(name)) {
	        callback = name;
	        name = '';
	      }
	      if (!callback) callback = this[name];
	      var router = this;
	      Backbone.history.route(route, function(fragment) {
	        var args = router._extractParameters(route, fragment);
	        if (router.execute(callback, args, name) !== false) {
	          router.trigger.apply(router, ['route:' + name].concat(args));
	          router.trigger('route', name, args);
	          Backbone.history.trigger('route', router, name, args);
	        }
	      });
	      return this;
	    },
	
	    // Execute a route handler with the provided parameters.  This is an
	    // excellent place to do pre-route setup or post-route cleanup.
	    execute: function(callback, args, name) {
	      if (callback) callback.apply(this, args);
	    },
	
	    // Simple proxy to `Backbone.history` to save a fragment into the history.
	    navigate: function(fragment, options) {
	      Backbone.history.navigate(fragment, options);
	      return this;
	    },
	
	    // Bind all defined routes to `Backbone.history`. We have to reverse the
	    // order of the routes here to support behavior where the most general
	    // routes can be defined at the bottom of the route map.
	    _bindRoutes: function() {
	      if (!this.routes) return;
	      this.routes = _.result(this, 'routes');
	      var route, routes = _.keys(this.routes);
	      while ((route = routes.pop()) != null) {
	        this.route(route, this.routes[route]);
	      }
	    },
	
	    // Convert a route string into a regular expression, suitable for matching
	    // against the current location hash.
	    _routeToRegExp: function(route) {
	      route = route.replace(escapeRegExp, '\\$&')
	                   .replace(optionalParam, '(?:$1)?')
	                   .replace(namedParam, function(match, optional) {
	                     return optional ? match : '([^/?]+)';
	                   })
	                   .replace(splatParam, '([^?]*?)');
	      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
	    },
	
	    // Given a route, and a URL fragment that it matches, return the array of
	    // extracted decoded parameters. Empty or unmatched parameters will be
	    // treated as `null` to normalize cross-browser behavior.
	    _extractParameters: function(route, fragment) {
	      var params = route.exec(fragment).slice(1);
	      return _.map(params, function(param, i) {
	        // Don't decode the search params.
	        if (i === params.length - 1) return param || null;
	        return param ? decodeURIComponent(param) : null;
	      });
	    }
	
	  });
	
	  // Backbone.History
	  // ----------------
	
	  // Handles cross-browser history management, based on either
	  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
	  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
	  // and URL fragments. If the browser supports neither (old IE, natch),
	  // falls back to polling.
	  var History = Backbone.History = function() {
	    this.handlers = [];
	    this.checkUrl = _.bind(this.checkUrl, this);
	
	    // Ensure that `History` can be used outside of the browser.
	    if (typeof window !== 'undefined') {
	      this.location = window.location;
	      this.history = window.history;
	    }
	  };
	
	  // Cached regex for stripping a leading hash/slash and trailing space.
	  var routeStripper = /^[#\/]|\s+$/g;
	
	  // Cached regex for stripping leading and trailing slashes.
	  var rootStripper = /^\/+|\/+$/g;
	
	  // Cached regex for stripping urls of hash.
	  var pathStripper = /#.*$/;
	
	  // Has the history handling already been started?
	  History.started = false;
	
	  // Set up all inheritable **Backbone.History** properties and methods.
	  _.extend(History.prototype, Events, {
	
	    // The default interval to poll for hash changes, if necessary, is
	    // twenty times a second.
	    interval: 50,
	
	    // Are we at the app root?
	    atRoot: function() {
	      var path = this.location.pathname.replace(/[^\/]$/, '$&/');
	      return path === this.root && !this.getSearch();
	    },
	
	    // Does the pathname match the root?
	    matchRoot: function() {
	      var path = this.decodeFragment(this.location.pathname);
	      var root = path.slice(0, this.root.length - 1) + '/';
	      return root === this.root;
	    },
	
	    // Unicode characters in `location.pathname` are percent encoded so they're
	    // decoded for comparison. `%25` should not be decoded since it may be part
	    // of an encoded parameter.
	    decodeFragment: function(fragment) {
	      return decodeURI(fragment.replace(/%25/g, '%2525'));
	    },
	
	    // In IE6, the hash fragment and search params are incorrect if the
	    // fragment contains `?`.
	    getSearch: function() {
	      var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
	      return match ? match[0] : '';
	    },
	
	    // Gets the true hash value. Cannot use location.hash directly due to bug
	    // in Firefox where location.hash will always be decoded.
	    getHash: function(window) {
	      var match = (window || this).location.href.match(/#(.*)$/);
	      return match ? match[1] : '';
	    },
	
	    // Get the pathname and search params, without the root.
	    getPath: function() {
	      var path = this.decodeFragment(
	        this.location.pathname + this.getSearch()
	      ).slice(this.root.length - 1);
	      return path.charAt(0) === '/' ? path.slice(1) : path;
	    },
	
	    // Get the cross-browser normalized URL fragment from the path or hash.
	    getFragment: function(fragment) {
	      if (fragment == null) {
	        if (this._usePushState || !this._wantsHashChange) {
	          fragment = this.getPath();
	        } else {
	          fragment = this.getHash();
	        }
	      }
	      return fragment.replace(routeStripper, '');
	    },
	
	    // Start the hash change handling, returning `true` if the current URL matches
	    // an existing route, and `false` otherwise.
	    start: function(options) {
	      if (History.started) throw new Error('Backbone.history has already been started');
	      History.started = true;
	
	      // Figure out the initial configuration. Do we need an iframe?
	      // Is pushState desired ... is it available?
	      this.options          = _.extend({root: '/'}, this.options, options);
	      this.root             = this.options.root;
	      this._wantsHashChange = this.options.hashChange !== false;
	      this._hasHashChange   = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
	      this._useHashChange   = this._wantsHashChange && this._hasHashChange;
	      this._wantsPushState  = !!this.options.pushState;
	      this._hasPushState    = !!(this.history && this.history.pushState);
	      this._usePushState    = this._wantsPushState && this._hasPushState;
	      this.fragment         = this.getFragment();
	
	      // Normalize root to always include a leading and trailing slash.
	      this.root = ('/' + this.root + '/').replace(rootStripper, '/');
	
	      // Transition from hashChange to pushState or vice versa if both are
	      // requested.
	      if (this._wantsHashChange && this._wantsPushState) {
	
	        // If we've started off with a route from a `pushState`-enabled
	        // browser, but we're currently in a browser that doesn't support it...
	        if (!this._hasPushState && !this.atRoot()) {
	          var root = this.root.slice(0, -1) || '/';
	          this.location.replace(root + '#' + this.getPath());
	          // Return immediately as browser will do redirect to new url
	          return true;
	
	        // Or if we've started out with a hash-based route, but we're currently
	        // in a browser where it could be `pushState`-based instead...
	        } else if (this._hasPushState && this.atRoot()) {
	          this.navigate(this.getHash(), {replace: true});
	        }
	
	      }
	
	      // Proxy an iframe to handle location events if the browser doesn't
	      // support the `hashchange` event, HTML5 history, or the user wants
	      // `hashChange` but not `pushState`.
	      if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
	        this.iframe = document.createElement('iframe');
	        this.iframe.src = 'javascript:0';
	        this.iframe.style.display = 'none';
	        this.iframe.tabIndex = -1;
	        var body = document.body;
	        // Using `appendChild` will throw on IE < 9 if the document is not ready.
	        var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
	        iWindow.document.open();
	        iWindow.document.close();
	        iWindow.location.hash = '#' + this.fragment;
	      }
	
	      // Add a cross-platform `addEventListener` shim for older browsers.
	      var addEventListener = window.addEventListener || function (eventName, listener) {
	        return attachEvent('on' + eventName, listener);
	      };
	
	      // Depending on whether we're using pushState or hashes, and whether
	      // 'onhashchange' is supported, determine how we check the URL state.
	      if (this._usePushState) {
	        addEventListener('popstate', this.checkUrl, false);
	      } else if (this._useHashChange && !this.iframe) {
	        addEventListener('hashchange', this.checkUrl, false);
	      } else if (this._wantsHashChange) {
	        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
	      }
	
	      if (!this.options.silent) return this.loadUrl();
	    },
	
	    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
	    // but possibly useful for unit testing Routers.
	    stop: function() {
	      // Add a cross-platform `removeEventListener` shim for older browsers.
	      var removeEventListener = window.removeEventListener || function (eventName, listener) {
	        return detachEvent('on' + eventName, listener);
	      };
	
	      // Remove window listeners.
	      if (this._usePushState) {
	        removeEventListener('popstate', this.checkUrl, false);
	      } else if (this._useHashChange && !this.iframe) {
	        removeEventListener('hashchange', this.checkUrl, false);
	      }
	
	      // Clean up the iframe if necessary.
	      if (this.iframe) {
	        document.body.removeChild(this.iframe);
	        this.iframe = null;
	      }
	
	      // Some environments will throw when clearing an undefined interval.
	      if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
	      History.started = false;
	    },
	
	    // Add a route to be tested when the fragment changes. Routes added later
	    // may override previous routes.
	    route: function(route, callback) {
	      this.handlers.unshift({route: route, callback: callback});
	    },
	
	    // Checks the current URL to see if it has changed, and if it has,
	    // calls `loadUrl`, normalizing across the hidden iframe.
	    checkUrl: function(e) {
	      var current = this.getFragment();
	
	      // If the user pressed the back button, the iframe's hash will have
	      // changed and we should use that for comparison.
	      if (current === this.fragment && this.iframe) {
	        current = this.getHash(this.iframe.contentWindow);
	      }
	
	      if (current === this.fragment) return false;
	      if (this.iframe) this.navigate(current);
	      this.loadUrl();
	    },
	
	    // Attempt to load the current URL fragment. If a route succeeds with a
	    // match, returns `true`. If no defined routes matches the fragment,
	    // returns `false`.
	    loadUrl: function(fragment) {
	      // If the root doesn't match, no routes can match either.
	      if (!this.matchRoot()) return false;
	      fragment = this.fragment = this.getFragment(fragment);
	      return _.some(this.handlers, function(handler) {
	        if (handler.route.test(fragment)) {
	          handler.callback(fragment);
	          return true;
	        }
	      });
	    },
	
	    // Save a fragment into the hash history, or replace the URL state if the
	    // 'replace' option is passed. You are responsible for properly URL-encoding
	    // the fragment in advance.
	    //
	    // The options object can contain `trigger: true` if you wish to have the
	    // route callback be fired (not usually desirable), or `replace: true`, if
	    // you wish to modify the current URL without adding an entry to the history.
	    navigate: function(fragment, options) {
	      if (!History.started) return false;
	      if (!options || options === true) options = {trigger: !!options};
	
	      // Normalize the fragment.
	      fragment = this.getFragment(fragment || '');
	
	      // Don't include a trailing slash on the root.
	      var root = this.root;
	      if (fragment === '' || fragment.charAt(0) === '?') {
	        root = root.slice(0, -1) || '/';
	      }
	      var url = root + fragment;
	
	      // Strip the hash and decode for matching.
	      fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
	
	      if (this.fragment === fragment) return;
	      this.fragment = fragment;
	
	      // If pushState is available, we use it to set the fragment as a real URL.
	      if (this._usePushState) {
	        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
	
	      // If hash changes haven't been explicitly disabled, update the hash
	      // fragment to store history.
	      } else if (this._wantsHashChange) {
	        this._updateHash(this.location, fragment, options.replace);
	        if (this.iframe && (fragment !== this.getHash(this.iframe.contentWindow))) {
	          var iWindow = this.iframe.contentWindow;
	
	          // Opening and closing the iframe tricks IE7 and earlier to push a
	          // history entry on hash-tag change.  When replace is true, we don't
	          // want this.
	          if (!options.replace) {
	            iWindow.document.open();
	            iWindow.document.close();
	          }
	
	          this._updateHash(iWindow.location, fragment, options.replace);
	        }
	
	      // If you've told us that you explicitly don't want fallback hashchange-
	      // based history, then `navigate` becomes a page refresh.
	      } else {
	        return this.location.assign(url);
	      }
	      if (options.trigger) return this.loadUrl(fragment);
	    },
	
	    // Update the hash location, either replacing the current entry, or adding
	    // a new one to the browser history.
	    _updateHash: function(location, fragment, replace) {
	      if (replace) {
	        var href = location.href.replace(/(javascript:|#).*$/, '');
	        location.replace(href + '#' + fragment);
	      } else {
	        // Some browsers require that `hash` contains a leading #.
	        location.hash = '#' + fragment;
	      }
	    }
	
	  });
	
	  // Create the default Backbone.history.
	  Backbone.history = new History;
	
	  // Helpers
	  // -------
	
	  // Helper function to correctly set up the prototype chain for subclasses.
	  // Similar to `goog.inherits`, but uses a hash of prototype properties and
	  // class properties to be extended.
	  var extend = function(protoProps, staticProps) {
	    var parent = this;
	    var child;
	
	    // The constructor function for the new subclass is either defined by you
	    // (the "constructor" property in your `extend` definition), or defaulted
	    // by us to simply call the parent constructor.
	    if (protoProps && _.has(protoProps, 'constructor')) {
	      child = protoProps.constructor;
	    } else {
	      child = function(){ return parent.apply(this, arguments); };
	    }
	
	    // Add static properties to the constructor function, if supplied.
	    _.extend(child, parent, staticProps);
	
	    // Set the prototype chain to inherit from `parent`, without calling
	    // `parent` constructor function.
	    var Surrogate = function(){ this.constructor = child; };
	    Surrogate.prototype = parent.prototype;
	    child.prototype = new Surrogate;
	
	    // Add prototype properties (instance properties) to the subclass,
	    // if supplied.
	    if (protoProps) _.extend(child.prototype, protoProps);
	
	    // Set a convenience property in case the parent's prototype is needed
	    // later.
	    child.__super__ = parent.prototype;
	
	    return child;
	  };
	
	  // Set up inheritance for the model, collection, router, view and history.
	  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
	
	  // Throw an error when a URL is needed, and none is supplied.
	  var urlError = function() {
	    throw new Error('A "url" property or function must be specified');
	  };
	
	  // Wrap an optional error callback with a fallback error event.
	  var wrapError = function(model, options) {
	    var error = options.error;
	    options.error = function(resp) {
	      if (error) error.call(options.context, model, resp, options);
	      model.trigger('error', model, resp, options);
	    };
	  };
	
	  return Backbone;
	
	}));
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

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

	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;//     Underscore.js 1.8.3
	//     http://underscorejs.org
	//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	//     Underscore may be freely distributed under the MIT license.
	
	(function() {
	
	  // Baseline setup
	  // --------------
	
	  // Establish the root object, `window` in the browser, or `exports` on the server.
	  var root = this;
	
	  // Save the previous value of the `_` variable.
	  var previousUnderscore = root._;
	
	  // Save bytes in the minified (but not gzipped) version:
	  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
	
	  // Create quick reference variables for speed access to core prototypes.
	  var
	    push             = ArrayProto.push,
	    slice            = ArrayProto.slice,
	    toString         = ObjProto.toString,
	    hasOwnProperty   = ObjProto.hasOwnProperty;
	
	  // All **ECMAScript 5** native function implementations that we hope to use
	  // are declared here.
	  var
	    nativeIsArray      = Array.isArray,
	    nativeKeys         = Object.keys,
	    nativeBind         = FuncProto.bind,
	    nativeCreate       = Object.create;
	
	  // Naked function reference for surrogate-prototype-swapping.
	  var Ctor = function(){};
	
	  // Create a safe reference to the Underscore object for use below.
	  var _ = function(obj) {
	    if (obj instanceof _) return obj;
	    if (!(this instanceof _)) return new _(obj);
	    this._wrapped = obj;
	  };
	
	  // Export the Underscore object for **Node.js**, with
	  // backwards-compatibility for the old `require()` API. If we're in
	  // the browser, add `_` as a global object.
	  if (true) {
	    if (typeof module !== 'undefined' && module.exports) {
	      exports = module.exports = _;
	    }
	    exports._ = _;
	  } else {
	    root._ = _;
	  }
	
	  // Current version.
	  _.VERSION = '1.8.3';
	
	  // Internal function that returns an efficient (for current engines) version
	  // of the passed-in callback, to be repeatedly applied in other Underscore
	  // functions.
	  var optimizeCb = function(func, context, argCount) {
	    if (context === void 0) return func;
	    switch (argCount == null ? 3 : argCount) {
	      case 1: return function(value) {
	        return func.call(context, value);
	      };
	      case 2: return function(value, other) {
	        return func.call(context, value, other);
	      };
	      case 3: return function(value, index, collection) {
	        return func.call(context, value, index, collection);
	      };
	      case 4: return function(accumulator, value, index, collection) {
	        return func.call(context, accumulator, value, index, collection);
	      };
	    }
	    return function() {
	      return func.apply(context, arguments);
	    };
	  };
	
	  // A mostly-internal function to generate callbacks that can be applied
	  // to each element in a collection, returning the desired result — either
	  // identity, an arbitrary callback, a property matcher, or a property accessor.
	  var cb = function(value, context, argCount) {
	    if (value == null) return _.identity;
	    if (_.isFunction(value)) return optimizeCb(value, context, argCount);
	    if (_.isObject(value)) return _.matcher(value);
	    return _.property(value);
	  };
	  _.iteratee = function(value, context) {
	    return cb(value, context, Infinity);
	  };
	
	  // An internal function for creating assigner functions.
	  var createAssigner = function(keysFunc, undefinedOnly) {
	    return function(obj) {
	      var length = arguments.length;
	      if (length < 2 || obj == null) return obj;
	      for (var index = 1; index < length; index++) {
	        var source = arguments[index],
	            keys = keysFunc(source),
	            l = keys.length;
	        for (var i = 0; i < l; i++) {
	          var key = keys[i];
	          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
	        }
	      }
	      return obj;
	    };
	  };
	
	  // An internal function for creating a new object that inherits from another.
	  var baseCreate = function(prototype) {
	    if (!_.isObject(prototype)) return {};
	    if (nativeCreate) return nativeCreate(prototype);
	    Ctor.prototype = prototype;
	    var result = new Ctor;
	    Ctor.prototype = null;
	    return result;
	  };
	
	  var property = function(key) {
	    return function(obj) {
	      return obj == null ? void 0 : obj[key];
	    };
	  };
	
	  // Helper for collection methods to determine whether a collection
	  // should be iterated as an array or as an object
	  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
	  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
	  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
	  var getLength = property('length');
	  var isArrayLike = function(collection) {
	    var length = getLength(collection);
	    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
	  };
	
	  // Collection Functions
	  // --------------------
	
	  // The cornerstone, an `each` implementation, aka `forEach`.
	  // Handles raw objects in addition to array-likes. Treats all
	  // sparse array-likes as if they were dense.
	  _.each = _.forEach = function(obj, iteratee, context) {
	    iteratee = optimizeCb(iteratee, context);
	    var i, length;
	    if (isArrayLike(obj)) {
	      for (i = 0, length = obj.length; i < length; i++) {
	        iteratee(obj[i], i, obj);
	      }
	    } else {
	      var keys = _.keys(obj);
	      for (i = 0, length = keys.length; i < length; i++) {
	        iteratee(obj[keys[i]], keys[i], obj);
	      }
	    }
	    return obj;
	  };
	
	  // Return the results of applying the iteratee to each element.
	  _.map = _.collect = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length,
	        results = Array(length);
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      results[index] = iteratee(obj[currentKey], currentKey, obj);
	    }
	    return results;
	  };
	
	  // Create a reducing function iterating left or right.
	  function createReduce(dir) {
	    // Optimized iterator function as using arguments.length
	    // in the main function will deoptimize the, see #1991.
	    function iterator(obj, iteratee, memo, keys, index, length) {
	      for (; index >= 0 && index < length; index += dir) {
	        var currentKey = keys ? keys[index] : index;
	        memo = iteratee(memo, obj[currentKey], currentKey, obj);
	      }
	      return memo;
	    }
	
	    return function(obj, iteratee, memo, context) {
	      iteratee = optimizeCb(iteratee, context, 4);
	      var keys = !isArrayLike(obj) && _.keys(obj),
	          length = (keys || obj).length,
	          index = dir > 0 ? 0 : length - 1;
	      // Determine the initial value if none is provided.
	      if (arguments.length < 3) {
	        memo = obj[keys ? keys[index] : index];
	        index += dir;
	      }
	      return iterator(obj, iteratee, memo, keys, index, length);
	    };
	  }
	
	  // **Reduce** builds up a single result from a list of values, aka `inject`,
	  // or `foldl`.
	  _.reduce = _.foldl = _.inject = createReduce(1);
	
	  // The right-associative version of reduce, also known as `foldr`.
	  _.reduceRight = _.foldr = createReduce(-1);
	
	  // Return the first value which passes a truth test. Aliased as `detect`.
	  _.find = _.detect = function(obj, predicate, context) {
	    var key;
	    if (isArrayLike(obj)) {
	      key = _.findIndex(obj, predicate, context);
	    } else {
	      key = _.findKey(obj, predicate, context);
	    }
	    if (key !== void 0 && key !== -1) return obj[key];
	  };
	
	  // Return all the elements that pass a truth test.
	  // Aliased as `select`.
	  _.filter = _.select = function(obj, predicate, context) {
	    var results = [];
	    predicate = cb(predicate, context);
	    _.each(obj, function(value, index, list) {
	      if (predicate(value, index, list)) results.push(value);
	    });
	    return results;
	  };
	
	  // Return all the elements for which a truth test fails.
	  _.reject = function(obj, predicate, context) {
	    return _.filter(obj, _.negate(cb(predicate)), context);
	  };
	
	  // Determine whether all of the elements match a truth test.
	  // Aliased as `all`.
	  _.every = _.all = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (!predicate(obj[currentKey], currentKey, obj)) return false;
	    }
	    return true;
	  };
	
	  // Determine if at least one element in the object matches a truth test.
	  // Aliased as `any`.
	  _.some = _.any = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (predicate(obj[currentKey], currentKey, obj)) return true;
	    }
	    return false;
	  };
	
	  // Determine if the array or object contains a given item (using `===`).
	  // Aliased as `includes` and `include`.
	  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
	    if (!isArrayLike(obj)) obj = _.values(obj);
	    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
	    return _.indexOf(obj, item, fromIndex) >= 0;
	  };
	
	  // Invoke a method (with arguments) on every item in a collection.
	  _.invoke = function(obj, method) {
	    var args = slice.call(arguments, 2);
	    var isFunc = _.isFunction(method);
	    return _.map(obj, function(value) {
	      var func = isFunc ? method : value[method];
	      return func == null ? func : func.apply(value, args);
	    });
	  };
	
	  // Convenience version of a common use case of `map`: fetching a property.
	  _.pluck = function(obj, key) {
	    return _.map(obj, _.property(key));
	  };
	
	  // Convenience version of a common use case of `filter`: selecting only objects
	  // containing specific `key:value` pairs.
	  _.where = function(obj, attrs) {
	    return _.filter(obj, _.matcher(attrs));
	  };
	
	  // Convenience version of a common use case of `find`: getting the first object
	  // containing specific `key:value` pairs.
	  _.findWhere = function(obj, attrs) {
	    return _.find(obj, _.matcher(attrs));
	  };
	
	  // Return the maximum element (or element-based computation).
	  _.max = function(obj, iteratee, context) {
	    var result = -Infinity, lastComputed = -Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value > result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };
	
	  // Return the minimum element (or element-based computation).
	  _.min = function(obj, iteratee, context) {
	    var result = Infinity, lastComputed = Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value < result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed < lastComputed || computed === Infinity && result === Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };
	
	  // Shuffle a collection, using the modern version of the
	  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
	  _.shuffle = function(obj) {
	    var set = isArrayLike(obj) ? obj : _.values(obj);
	    var length = set.length;
	    var shuffled = Array(length);
	    for (var index = 0, rand; index < length; index++) {
	      rand = _.random(0, index);
	      if (rand !== index) shuffled[index] = shuffled[rand];
	      shuffled[rand] = set[index];
	    }
	    return shuffled;
	  };
	
	  // Sample **n** random values from a collection.
	  // If **n** is not specified, returns a single random element.
	  // The internal `guard` argument allows it to work with `map`.
	  _.sample = function(obj, n, guard) {
	    if (n == null || guard) {
	      if (!isArrayLike(obj)) obj = _.values(obj);
	      return obj[_.random(obj.length - 1)];
	    }
	    return _.shuffle(obj).slice(0, Math.max(0, n));
	  };
	
	  // Sort the object's values by a criterion produced by an iteratee.
	  _.sortBy = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    return _.pluck(_.map(obj, function(value, index, list) {
	      return {
	        value: value,
	        index: index,
	        criteria: iteratee(value, index, list)
	      };
	    }).sort(function(left, right) {
	      var a = left.criteria;
	      var b = right.criteria;
	      if (a !== b) {
	        if (a > b || a === void 0) return 1;
	        if (a < b || b === void 0) return -1;
	      }
	      return left.index - right.index;
	    }), 'value');
	  };
	
	  // An internal function used for aggregate "group by" operations.
	  var group = function(behavior) {
	    return function(obj, iteratee, context) {
	      var result = {};
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index) {
	        var key = iteratee(value, index, obj);
	        behavior(result, value, key);
	      });
	      return result;
	    };
	  };
	
	  // Groups the object's values by a criterion. Pass either a string attribute
	  // to group by, or a function that returns the criterion.
	  _.groupBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key].push(value); else result[key] = [value];
	  });
	
	  // Indexes the object's values by a criterion, similar to `groupBy`, but for
	  // when you know that your index values will be unique.
	  _.indexBy = group(function(result, value, key) {
	    result[key] = value;
	  });
	
	  // Counts instances of an object that group by a certain criterion. Pass
	  // either a string attribute to count by, or a function that returns the
	  // criterion.
	  _.countBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key]++; else result[key] = 1;
	  });
	
	  // Safely create a real, live array from anything iterable.
	  _.toArray = function(obj) {
	    if (!obj) return [];
	    if (_.isArray(obj)) return slice.call(obj);
	    if (isArrayLike(obj)) return _.map(obj, _.identity);
	    return _.values(obj);
	  };
	
	  // Return the number of elements in an object.
	  _.size = function(obj) {
	    if (obj == null) return 0;
	    return isArrayLike(obj) ? obj.length : _.keys(obj).length;
	  };
	
	  // Split a collection into two arrays: one whose elements all satisfy the given
	  // predicate, and one whose elements all do not satisfy the predicate.
	  _.partition = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var pass = [], fail = [];
	    _.each(obj, function(value, key, obj) {
	      (predicate(value, key, obj) ? pass : fail).push(value);
	    });
	    return [pass, fail];
	  };
	
	  // Array Functions
	  // ---------------
	
	  // Get the first element of an array. Passing **n** will return the first N
	  // values in the array. Aliased as `head` and `take`. The **guard** check
	  // allows it to work with `_.map`.
	  _.first = _.head = _.take = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[0];
	    return _.initial(array, array.length - n);
	  };
	
	  // Returns everything but the last entry of the array. Especially useful on
	  // the arguments object. Passing **n** will return all the values in
	  // the array, excluding the last N.
	  _.initial = function(array, n, guard) {
	    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
	  };
	
	  // Get the last element of an array. Passing **n** will return the last N
	  // values in the array.
	  _.last = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[array.length - 1];
	    return _.rest(array, Math.max(0, array.length - n));
	  };
	
	  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
	  // Especially useful on the arguments object. Passing an **n** will return
	  // the rest N values in the array.
	  _.rest = _.tail = _.drop = function(array, n, guard) {
	    return slice.call(array, n == null || guard ? 1 : n);
	  };
	
	  // Trim out all falsy values from an array.
	  _.compact = function(array) {
	    return _.filter(array, _.identity);
	  };
	
	  // Internal implementation of a recursive `flatten` function.
	  var flatten = function(input, shallow, strict, startIndex) {
	    var output = [], idx = 0;
	    for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
	      var value = input[i];
	      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
	        //flatten current level of array or arguments object
	        if (!shallow) value = flatten(value, shallow, strict);
	        var j = 0, len = value.length;
	        output.length += len;
	        while (j < len) {
	          output[idx++] = value[j++];
	        }
	      } else if (!strict) {
	        output[idx++] = value;
	      }
	    }
	    return output;
	  };
	
	  // Flatten out an array, either recursively (by default), or just one level.
	  _.flatten = function(array, shallow) {
	    return flatten(array, shallow, false);
	  };
	
	  // Return a version of the array that does not contain the specified value(s).
	  _.without = function(array) {
	    return _.difference(array, slice.call(arguments, 1));
	  };
	
	  // Produce a duplicate-free version of the array. If the array has already
	  // been sorted, you have the option of using a faster algorithm.
	  // Aliased as `unique`.
	  _.uniq = _.unique = function(array, isSorted, iteratee, context) {
	    if (!_.isBoolean(isSorted)) {
	      context = iteratee;
	      iteratee = isSorted;
	      isSorted = false;
	    }
	    if (iteratee != null) iteratee = cb(iteratee, context);
	    var result = [];
	    var seen = [];
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var value = array[i],
	          computed = iteratee ? iteratee(value, i, array) : value;
	      if (isSorted) {
	        if (!i || seen !== computed) result.push(value);
	        seen = computed;
	      } else if (iteratee) {
	        if (!_.contains(seen, computed)) {
	          seen.push(computed);
	          result.push(value);
	        }
	      } else if (!_.contains(result, value)) {
	        result.push(value);
	      }
	    }
	    return result;
	  };
	
	  // Produce an array that contains the union: each distinct element from all of
	  // the passed-in arrays.
	  _.union = function() {
	    return _.uniq(flatten(arguments, true, true));
	  };
	
	  // Produce an array that contains every item shared between all the
	  // passed-in arrays.
	  _.intersection = function(array) {
	    var result = [];
	    var argsLength = arguments.length;
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var item = array[i];
	      if (_.contains(result, item)) continue;
	      for (var j = 1; j < argsLength; j++) {
	        if (!_.contains(arguments[j], item)) break;
	      }
	      if (j === argsLength) result.push(item);
	    }
	    return result;
	  };
	
	  // Take the difference between one array and a number of other arrays.
	  // Only the elements present in just the first array will remain.
	  _.difference = function(array) {
	    var rest = flatten(arguments, true, true, 1);
	    return _.filter(array, function(value){
	      return !_.contains(rest, value);
	    });
	  };
	
	  // Zip together multiple lists into a single array -- elements that share
	  // an index go together.
	  _.zip = function() {
	    return _.unzip(arguments);
	  };
	
	  // Complement of _.zip. Unzip accepts an array of arrays and groups
	  // each array's elements on shared indices
	  _.unzip = function(array) {
	    var length = array && _.max(array, getLength).length || 0;
	    var result = Array(length);
	
	    for (var index = 0; index < length; index++) {
	      result[index] = _.pluck(array, index);
	    }
	    return result;
	  };
	
	  // Converts lists into objects. Pass either a single array of `[key, value]`
	  // pairs, or two parallel arrays of the same length -- one of keys, and one of
	  // the corresponding values.
	  _.object = function(list, values) {
	    var result = {};
	    for (var i = 0, length = getLength(list); i < length; i++) {
	      if (values) {
	        result[list[i]] = values[i];
	      } else {
	        result[list[i][0]] = list[i][1];
	      }
	    }
	    return result;
	  };
	
	  // Generator function to create the findIndex and findLastIndex functions
	  function createPredicateIndexFinder(dir) {
	    return function(array, predicate, context) {
	      predicate = cb(predicate, context);
	      var length = getLength(array);
	      var index = dir > 0 ? 0 : length - 1;
	      for (; index >= 0 && index < length; index += dir) {
	        if (predicate(array[index], index, array)) return index;
	      }
	      return -1;
	    };
	  }
	
	  // Returns the first index on an array-like that passes a predicate test
	  _.findIndex = createPredicateIndexFinder(1);
	  _.findLastIndex = createPredicateIndexFinder(-1);
	
	  // Use a comparator function to figure out the smallest index at which
	  // an object should be inserted so as to maintain order. Uses binary search.
	  _.sortedIndex = function(array, obj, iteratee, context) {
	    iteratee = cb(iteratee, context, 1);
	    var value = iteratee(obj);
	    var low = 0, high = getLength(array);
	    while (low < high) {
	      var mid = Math.floor((low + high) / 2);
	      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
	    }
	    return low;
	  };
	
	  // Generator function to create the indexOf and lastIndexOf functions
	  function createIndexFinder(dir, predicateFind, sortedIndex) {
	    return function(array, item, idx) {
	      var i = 0, length = getLength(array);
	      if (typeof idx == 'number') {
	        if (dir > 0) {
	            i = idx >= 0 ? idx : Math.max(idx + length, i);
	        } else {
	            length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
	        }
	      } else if (sortedIndex && idx && length) {
	        idx = sortedIndex(array, item);
	        return array[idx] === item ? idx : -1;
	      }
	      if (item !== item) {
	        idx = predicateFind(slice.call(array, i, length), _.isNaN);
	        return idx >= 0 ? idx + i : -1;
	      }
	      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
	        if (array[idx] === item) return idx;
	      }
	      return -1;
	    };
	  }
	
	  // Return the position of the first occurrence of an item in an array,
	  // or -1 if the item is not included in the array.
	  // If the array is large and already in sort order, pass `true`
	  // for **isSorted** to use binary search.
	  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
	  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
	
	  // Generate an integer Array containing an arithmetic progression. A port of
	  // the native Python `range()` function. See
	  // [the Python documentation](http://docs.python.org/library/functions.html#range).
	  _.range = function(start, stop, step) {
	    if (stop == null) {
	      stop = start || 0;
	      start = 0;
	    }
	    step = step || 1;
	
	    var length = Math.max(Math.ceil((stop - start) / step), 0);
	    var range = Array(length);
	
	    for (var idx = 0; idx < length; idx++, start += step) {
	      range[idx] = start;
	    }
	
	    return range;
	  };
	
	  // Function (ahem) Functions
	  // ------------------
	
	  // Determines whether to execute a function as a constructor
	  // or a normal function with the provided arguments
	  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
	    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
	    var self = baseCreate(sourceFunc.prototype);
	    var result = sourceFunc.apply(self, args);
	    if (_.isObject(result)) return result;
	    return self;
	  };
	
	  // Create a function bound to a given object (assigning `this`, and arguments,
	  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
	  // available.
	  _.bind = function(func, context) {
	    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
	    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
	    var args = slice.call(arguments, 2);
	    var bound = function() {
	      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
	    };
	    return bound;
	  };
	
	  // Partially apply a function by creating a version that has had some of its
	  // arguments pre-filled, without changing its dynamic `this` context. _ acts
	  // as a placeholder, allowing any combination of arguments to be pre-filled.
	  _.partial = function(func) {
	    var boundArgs = slice.call(arguments, 1);
	    var bound = function() {
	      var position = 0, length = boundArgs.length;
	      var args = Array(length);
	      for (var i = 0; i < length; i++) {
	        args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
	      }
	      while (position < arguments.length) args.push(arguments[position++]);
	      return executeBound(func, bound, this, this, args);
	    };
	    return bound;
	  };
	
	  // Bind a number of an object's methods to that object. Remaining arguments
	  // are the method names to be bound. Useful for ensuring that all callbacks
	  // defined on an object belong to it.
	  _.bindAll = function(obj) {
	    var i, length = arguments.length, key;
	    if (length <= 1) throw new Error('bindAll must be passed function names');
	    for (i = 1; i < length; i++) {
	      key = arguments[i];
	      obj[key] = _.bind(obj[key], obj);
	    }
	    return obj;
	  };
	
	  // Memoize an expensive function by storing its results.
	  _.memoize = function(func, hasher) {
	    var memoize = function(key) {
	      var cache = memoize.cache;
	      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
	      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
	      return cache[address];
	    };
	    memoize.cache = {};
	    return memoize;
	  };
	
	  // Delays a function for the given number of milliseconds, and then calls
	  // it with the arguments supplied.
	  _.delay = function(func, wait) {
	    var args = slice.call(arguments, 2);
	    return setTimeout(function(){
	      return func.apply(null, args);
	    }, wait);
	  };
	
	  // Defers a function, scheduling it to run after the current call stack has
	  // cleared.
	  _.defer = _.partial(_.delay, _, 1);
	
	  // Returns a function, that, when invoked, will only be triggered at most once
	  // during a given window of time. Normally, the throttled function will run
	  // as much as it can, without ever going more than once per `wait` duration;
	  // but if you'd like to disable the execution on the leading edge, pass
	  // `{leading: false}`. To disable execution on the trailing edge, ditto.
	  _.throttle = function(func, wait, options) {
	    var context, args, result;
	    var timeout = null;
	    var previous = 0;
	    if (!options) options = {};
	    var later = function() {
	      previous = options.leading === false ? 0 : _.now();
	      timeout = null;
	      result = func.apply(context, args);
	      if (!timeout) context = args = null;
	    };
	    return function() {
	      var now = _.now();
	      if (!previous && options.leading === false) previous = now;
	      var remaining = wait - (now - previous);
	      context = this;
	      args = arguments;
	      if (remaining <= 0 || remaining > wait) {
	        if (timeout) {
	          clearTimeout(timeout);
	          timeout = null;
	        }
	        previous = now;
	        result = func.apply(context, args);
	        if (!timeout) context = args = null;
	      } else if (!timeout && options.trailing !== false) {
	        timeout = setTimeout(later, remaining);
	      }
	      return result;
	    };
	  };
	
	  // Returns a function, that, as long as it continues to be invoked, will not
	  // be triggered. The function will be called after it stops being called for
	  // N milliseconds. If `immediate` is passed, trigger the function on the
	  // leading edge, instead of the trailing.
	  _.debounce = function(func, wait, immediate) {
	    var timeout, args, context, timestamp, result;
	
	    var later = function() {
	      var last = _.now() - timestamp;
	
	      if (last < wait && last >= 0) {
	        timeout = setTimeout(later, wait - last);
	      } else {
	        timeout = null;
	        if (!immediate) {
	          result = func.apply(context, args);
	          if (!timeout) context = args = null;
	        }
	      }
	    };
	
	    return function() {
	      context = this;
	      args = arguments;
	      timestamp = _.now();
	      var callNow = immediate && !timeout;
	      if (!timeout) timeout = setTimeout(later, wait);
	      if (callNow) {
	        result = func.apply(context, args);
	        context = args = null;
	      }
	
	      return result;
	    };
	  };
	
	  // Returns the first function passed as an argument to the second,
	  // allowing you to adjust arguments, run code before and after, and
	  // conditionally execute the original function.
	  _.wrap = function(func, wrapper) {
	    return _.partial(wrapper, func);
	  };
	
	  // Returns a negated version of the passed-in predicate.
	  _.negate = function(predicate) {
	    return function() {
	      return !predicate.apply(this, arguments);
	    };
	  };
	
	  // Returns a function that is the composition of a list of functions, each
	  // consuming the return value of the function that follows.
	  _.compose = function() {
	    var args = arguments;
	    var start = args.length - 1;
	    return function() {
	      var i = start;
	      var result = args[start].apply(this, arguments);
	      while (i--) result = args[i].call(this, result);
	      return result;
	    };
	  };
	
	  // Returns a function that will only be executed on and after the Nth call.
	  _.after = function(times, func) {
	    return function() {
	      if (--times < 1) {
	        return func.apply(this, arguments);
	      }
	    };
	  };
	
	  // Returns a function that will only be executed up to (but not including) the Nth call.
	  _.before = function(times, func) {
	    var memo;
	    return function() {
	      if (--times > 0) {
	        memo = func.apply(this, arguments);
	      }
	      if (times <= 1) func = null;
	      return memo;
	    };
	  };
	
	  // Returns a function that will be executed at most one time, no matter how
	  // often you call it. Useful for lazy initialization.
	  _.once = _.partial(_.before, 2);
	
	  // Object Functions
	  // ----------------
	
	  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
	  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
	  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
	                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
	
	  function collectNonEnumProps(obj, keys) {
	    var nonEnumIdx = nonEnumerableProps.length;
	    var constructor = obj.constructor;
	    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
	
	    // Constructor is a special case.
	    var prop = 'constructor';
	    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
	
	    while (nonEnumIdx--) {
	      prop = nonEnumerableProps[nonEnumIdx];
	      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
	        keys.push(prop);
	      }
	    }
	  }
	
	  // Retrieve the names of an object's own properties.
	  // Delegates to **ECMAScript 5**'s native `Object.keys`
	  _.keys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    if (nativeKeys) return nativeKeys(obj);
	    var keys = [];
	    for (var key in obj) if (_.has(obj, key)) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };
	
	  // Retrieve all the property names of an object.
	  _.allKeys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    var keys = [];
	    for (var key in obj) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };
	
	  // Retrieve the values of an object's properties.
	  _.values = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var values = Array(length);
	    for (var i = 0; i < length; i++) {
	      values[i] = obj[keys[i]];
	    }
	    return values;
	  };
	
	  // Returns the results of applying the iteratee to each element of the object
	  // In contrast to _.map it returns an object
	  _.mapObject = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys =  _.keys(obj),
	          length = keys.length,
	          results = {},
	          currentKey;
	      for (var index = 0; index < length; index++) {
	        currentKey = keys[index];
	        results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
	      }
	      return results;
	  };
	
	  // Convert an object into a list of `[key, value]` pairs.
	  _.pairs = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var pairs = Array(length);
	    for (var i = 0; i < length; i++) {
	      pairs[i] = [keys[i], obj[keys[i]]];
	    }
	    return pairs;
	  };
	
	  // Invert the keys and values of an object. The values must be serializable.
	  _.invert = function(obj) {
	    var result = {};
	    var keys = _.keys(obj);
	    for (var i = 0, length = keys.length; i < length; i++) {
	      result[obj[keys[i]]] = keys[i];
	    }
	    return result;
	  };
	
	  // Return a sorted list of the function names available on the object.
	  // Aliased as `methods`
	  _.functions = _.methods = function(obj) {
	    var names = [];
	    for (var key in obj) {
	      if (_.isFunction(obj[key])) names.push(key);
	    }
	    return names.sort();
	  };
	
	  // Extend a given object with all the properties in passed-in object(s).
	  _.extend = createAssigner(_.allKeys);
	
	  // Assigns a given object with all the own properties in the passed-in object(s)
	  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
	  _.extendOwn = _.assign = createAssigner(_.keys);
	
	  // Returns the first key on an object that passes a predicate test
	  _.findKey = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = _.keys(obj), key;
	    for (var i = 0, length = keys.length; i < length; i++) {
	      key = keys[i];
	      if (predicate(obj[key], key, obj)) return key;
	    }
	  };
	
	  // Return a copy of the object only containing the whitelisted properties.
	  _.pick = function(object, oiteratee, context) {
	    var result = {}, obj = object, iteratee, keys;
	    if (obj == null) return result;
	    if (_.isFunction(oiteratee)) {
	      keys = _.allKeys(obj);
	      iteratee = optimizeCb(oiteratee, context);
	    } else {
	      keys = flatten(arguments, false, false, 1);
	      iteratee = function(value, key, obj) { return key in obj; };
	      obj = Object(obj);
	    }
	    for (var i = 0, length = keys.length; i < length; i++) {
	      var key = keys[i];
	      var value = obj[key];
	      if (iteratee(value, key, obj)) result[key] = value;
	    }
	    return result;
	  };
	
	   // Return a copy of the object without the blacklisted properties.
	  _.omit = function(obj, iteratee, context) {
	    if (_.isFunction(iteratee)) {
	      iteratee = _.negate(iteratee);
	    } else {
	      var keys = _.map(flatten(arguments, false, false, 1), String);
	      iteratee = function(value, key) {
	        return !_.contains(keys, key);
	      };
	    }
	    return _.pick(obj, iteratee, context);
	  };
	
	  // Fill in a given object with default properties.
	  _.defaults = createAssigner(_.allKeys, true);
	
	  // Creates an object that inherits from the given prototype object.
	  // If additional properties are provided then they will be added to the
	  // created object.
	  _.create = function(prototype, props) {
	    var result = baseCreate(prototype);
	    if (props) _.extendOwn(result, props);
	    return result;
	  };
	
	  // Create a (shallow-cloned) duplicate of an object.
	  _.clone = function(obj) {
	    if (!_.isObject(obj)) return obj;
	    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
	  };
	
	  // Invokes interceptor with the obj, and then returns obj.
	  // The primary purpose of this method is to "tap into" a method chain, in
	  // order to perform operations on intermediate results within the chain.
	  _.tap = function(obj, interceptor) {
	    interceptor(obj);
	    return obj;
	  };
	
	  // Returns whether an object has a given set of `key:value` pairs.
	  _.isMatch = function(object, attrs) {
	    var keys = _.keys(attrs), length = keys.length;
	    if (object == null) return !length;
	    var obj = Object(object);
	    for (var i = 0; i < length; i++) {
	      var key = keys[i];
	      if (attrs[key] !== obj[key] || !(key in obj)) return false;
	    }
	    return true;
	  };
	
	
	  // Internal recursive comparison function for `isEqual`.
	  var eq = function(a, b, aStack, bStack) {
	    // Identical objects are equal. `0 === -0`, but they aren't identical.
	    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
	    if (a === b) return a !== 0 || 1 / a === 1 / b;
	    // A strict comparison is necessary because `null == undefined`.
	    if (a == null || b == null) return a === b;
	    // Unwrap any wrapped objects.
	    if (a instanceof _) a = a._wrapped;
	    if (b instanceof _) b = b._wrapped;
	    // Compare `[[Class]]` names.
	    var className = toString.call(a);
	    if (className !== toString.call(b)) return false;
	    switch (className) {
	      // Strings, numbers, regular expressions, dates, and booleans are compared by value.
	      case '[object RegExp]':
	      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
	      case '[object String]':
	        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
	        // equivalent to `new String("5")`.
	        return '' + a === '' + b;
	      case '[object Number]':
	        // `NaN`s are equivalent, but non-reflexive.
	        // Object(NaN) is equivalent to NaN
	        if (+a !== +a) return +b !== +b;
	        // An `egal` comparison is performed for other numeric values.
	        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
	      case '[object Date]':
	      case '[object Boolean]':
	        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
	        // millisecond representations. Note that invalid dates with millisecond representations
	        // of `NaN` are not equivalent.
	        return +a === +b;
	    }
	
	    var areArrays = className === '[object Array]';
	    if (!areArrays) {
	      if (typeof a != 'object' || typeof b != 'object') return false;
	
	      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
	      // from different frames are.
	      var aCtor = a.constructor, bCtor = b.constructor;
	      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
	                               _.isFunction(bCtor) && bCtor instanceof bCtor)
	                          && ('constructor' in a && 'constructor' in b)) {
	        return false;
	      }
	    }
	    // Assume equality for cyclic structures. The algorithm for detecting cyclic
	    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
	
	    // Initializing stack of traversed objects.
	    // It's done here since we only need them for objects and arrays comparison.
	    aStack = aStack || [];
	    bStack = bStack || [];
	    var length = aStack.length;
	    while (length--) {
	      // Linear search. Performance is inversely proportional to the number of
	      // unique nested structures.
	      if (aStack[length] === a) return bStack[length] === b;
	    }
	
	    // Add the first object to the stack of traversed objects.
	    aStack.push(a);
	    bStack.push(b);
	
	    // Recursively compare objects and arrays.
	    if (areArrays) {
	      // Compare array lengths to determine if a deep comparison is necessary.
	      length = a.length;
	      if (length !== b.length) return false;
	      // Deep compare the contents, ignoring non-numeric properties.
	      while (length--) {
	        if (!eq(a[length], b[length], aStack, bStack)) return false;
	      }
	    } else {
	      // Deep compare objects.
	      var keys = _.keys(a), key;
	      length = keys.length;
	      // Ensure that both objects contain the same number of properties before comparing deep equality.
	      if (_.keys(b).length !== length) return false;
	      while (length--) {
	        // Deep compare each member
	        key = keys[length];
	        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
	      }
	    }
	    // Remove the first object from the stack of traversed objects.
	    aStack.pop();
	    bStack.pop();
	    return true;
	  };
	
	  // Perform a deep comparison to check if two objects are equal.
	  _.isEqual = function(a, b) {
	    return eq(a, b);
	  };
	
	  // Is a given array, string, or object empty?
	  // An "empty" object has no enumerable own-properties.
	  _.isEmpty = function(obj) {
	    if (obj == null) return true;
	    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
	    return _.keys(obj).length === 0;
	  };
	
	  // Is a given value a DOM element?
	  _.isElement = function(obj) {
	    return !!(obj && obj.nodeType === 1);
	  };
	
	  // Is a given value an array?
	  // Delegates to ECMA5's native Array.isArray
	  _.isArray = nativeIsArray || function(obj) {
	    return toString.call(obj) === '[object Array]';
	  };
	
	  // Is a given variable an object?
	  _.isObject = function(obj) {
	    var type = typeof obj;
	    return type === 'function' || type === 'object' && !!obj;
	  };
	
	  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
	  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
	    _['is' + name] = function(obj) {
	      return toString.call(obj) === '[object ' + name + ']';
	    };
	  });
	
	  // Define a fallback version of the method in browsers (ahem, IE < 9), where
	  // there isn't any inspectable "Arguments" type.
	  if (!_.isArguments(arguments)) {
	    _.isArguments = function(obj) {
	      return _.has(obj, 'callee');
	    };
	  }
	
	  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
	  // IE 11 (#1621), and in Safari 8 (#1929).
	  if (typeof /./ != 'function' && typeof Int8Array != 'object') {
	    _.isFunction = function(obj) {
	      return typeof obj == 'function' || false;
	    };
	  }
	
	  // Is a given object a finite number?
	  _.isFinite = function(obj) {
	    return isFinite(obj) && !isNaN(parseFloat(obj));
	  };
	
	  // Is the given value `NaN`? (NaN is the only number which does not equal itself).
	  _.isNaN = function(obj) {
	    return _.isNumber(obj) && obj !== +obj;
	  };
	
	  // Is a given value a boolean?
	  _.isBoolean = function(obj) {
	    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
	  };
	
	  // Is a given value equal to null?
	  _.isNull = function(obj) {
	    return obj === null;
	  };
	
	  // Is a given variable undefined?
	  _.isUndefined = function(obj) {
	    return obj === void 0;
	  };
	
	  // Shortcut function for checking if an object has a given property directly
	  // on itself (in other words, not on a prototype).
	  _.has = function(obj, key) {
	    return obj != null && hasOwnProperty.call(obj, key);
	  };
	
	  // Utility Functions
	  // -----------------
	
	  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
	  // previous owner. Returns a reference to the Underscore object.
	  _.noConflict = function() {
	    root._ = previousUnderscore;
	    return this;
	  };
	
	  // Keep the identity function around for default iteratees.
	  _.identity = function(value) {
	    return value;
	  };
	
	  // Predicate-generating functions. Often useful outside of Underscore.
	  _.constant = function(value) {
	    return function() {
	      return value;
	    };
	  };
	
	  _.noop = function(){};
	
	  _.property = property;
	
	  // Generates a function for a given object that returns a given property.
	  _.propertyOf = function(obj) {
	    return obj == null ? function(){} : function(key) {
	      return obj[key];
	    };
	  };
	
	  // Returns a predicate for checking whether an object has a given set of
	  // `key:value` pairs.
	  _.matcher = _.matches = function(attrs) {
	    attrs = _.extendOwn({}, attrs);
	    return function(obj) {
	      return _.isMatch(obj, attrs);
	    };
	  };
	
	  // Run a function **n** times.
	  _.times = function(n, iteratee, context) {
	    var accum = Array(Math.max(0, n));
	    iteratee = optimizeCb(iteratee, context, 1);
	    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
	    return accum;
	  };
	
	  // Return a random integer between min and max (inclusive).
	  _.random = function(min, max) {
	    if (max == null) {
	      max = min;
	      min = 0;
	    }
	    return min + Math.floor(Math.random() * (max - min + 1));
	  };
	
	  // A (possibly faster) way to get the current timestamp as an integer.
	  _.now = Date.now || function() {
	    return new Date().getTime();
	  };
	
	   // List of HTML entities for escaping.
	  var escapeMap = {
	    '&': '&amp;',
	    '<': '&lt;',
	    '>': '&gt;',
	    '"': '&quot;',
	    "'": '&#x27;',
	    '`': '&#x60;'
	  };
	  var unescapeMap = _.invert(escapeMap);
	
	  // Functions for escaping and unescaping strings to/from HTML interpolation.
	  var createEscaper = function(map) {
	    var escaper = function(match) {
	      return map[match];
	    };
	    // Regexes for identifying a key that needs to be escaped
	    var source = '(?:' + _.keys(map).join('|') + ')';
	    var testRegexp = RegExp(source);
	    var replaceRegexp = RegExp(source, 'g');
	    return function(string) {
	      string = string == null ? '' : '' + string;
	      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
	    };
	  };
	  _.escape = createEscaper(escapeMap);
	  _.unescape = createEscaper(unescapeMap);
	
	  // If the value of the named `property` is a function then invoke it with the
	  // `object` as context; otherwise, return it.
	  _.result = function(object, property, fallback) {
	    var value = object == null ? void 0 : object[property];
	    if (value === void 0) {
	      value = fallback;
	    }
	    return _.isFunction(value) ? value.call(object) : value;
	  };
	
	  // Generate a unique integer id (unique within the entire client session).
	  // Useful for temporary DOM ids.
	  var idCounter = 0;
	  _.uniqueId = function(prefix) {
	    var id = ++idCounter + '';
	    return prefix ? prefix + id : id;
	  };
	
	  // By default, Underscore uses ERB-style template delimiters, change the
	  // following template settings to use alternative delimiters.
	  _.templateSettings = {
	    evaluate    : /<%([\s\S]+?)%>/g,
	    interpolate : /<%=([\s\S]+?)%>/g,
	    escape      : /<%-([\s\S]+?)%>/g
	  };
	
	  // When customizing `templateSettings`, if you don't want to define an
	  // interpolation, evaluation or escaping regex, we need one that is
	  // guaranteed not to match.
	  var noMatch = /(.)^/;
	
	  // Certain characters need to be escaped so that they can be put into a
	  // string literal.
	  var escapes = {
	    "'":      "'",
	    '\\':     '\\',
	    '\r':     'r',
	    '\n':     'n',
	    '\u2028': 'u2028',
	    '\u2029': 'u2029'
	  };
	
	  var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
	
	  var escapeChar = function(match) {
	    return '\\' + escapes[match];
	  };
	
	  // JavaScript micro-templating, similar to John Resig's implementation.
	  // Underscore templating handles arbitrary delimiters, preserves whitespace,
	  // and correctly escapes quotes within interpolated code.
	  // NB: `oldSettings` only exists for backwards compatibility.
	  _.template = function(text, settings, oldSettings) {
	    if (!settings && oldSettings) settings = oldSettings;
	    settings = _.defaults({}, settings, _.templateSettings);
	
	    // Combine delimiters into one regular expression via alternation.
	    var matcher = RegExp([
	      (settings.escape || noMatch).source,
	      (settings.interpolate || noMatch).source,
	      (settings.evaluate || noMatch).source
	    ].join('|') + '|$', 'g');
	
	    // Compile the template source, escaping string literals appropriately.
	    var index = 0;
	    var source = "__p+='";
	    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
	      source += text.slice(index, offset).replace(escaper, escapeChar);
	      index = offset + match.length;
	
	      if (escape) {
	        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
	      } else if (interpolate) {
	        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
	      } else if (evaluate) {
	        source += "';\n" + evaluate + "\n__p+='";
	      }
	
	      // Adobe VMs need the match returned to produce the correct offest.
	      return match;
	    });
	    source += "';\n";
	
	    // If a variable is not specified, place data values in local scope.
	    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
	
	    source = "var __t,__p='',__j=Array.prototype.join," +
	      "print=function(){__p+=__j.call(arguments,'');};\n" +
	      source + 'return __p;\n';
	
	    try {
	      var render = new Function(settings.variable || 'obj', '_', source);
	    } catch (e) {
	      e.source = source;
	      throw e;
	    }
	
	    var template = function(data) {
	      return render.call(this, data, _);
	    };
	
	    // Provide the compiled source as a convenience for precompilation.
	    var argument = settings.variable || 'obj';
	    template.source = 'function(' + argument + '){\n' + source + '}';
	
	    return template;
	  };
	
	  // Add a "chain" function. Start chaining a wrapped Underscore object.
	  _.chain = function(obj) {
	    var instance = _(obj);
	    instance._chain = true;
	    return instance;
	  };
	
	  // OOP
	  // ---------------
	  // If Underscore is called as a function, it returns a wrapped object that
	  // can be used OO-style. This wrapper holds altered versions of all the
	  // underscore functions. Wrapped objects may be chained.
	
	  // Helper function to continue chaining intermediate results.
	  var result = function(instance, obj) {
	    return instance._chain ? _(obj).chain() : obj;
	  };
	
	  // Add your own custom functions to the Underscore object.
	  _.mixin = function(obj) {
	    _.each(_.functions(obj), function(name) {
	      var func = _[name] = obj[name];
	      _.prototype[name] = function() {
	        var args = [this._wrapped];
	        push.apply(args, arguments);
	        return result(this, func.apply(_, args));
	      };
	    });
	  };
	
	  // Add all of the Underscore functions to the wrapper object.
	  _.mixin(_);
	
	  // Add all mutator Array functions to the wrapper.
	  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      var obj = this._wrapped;
	      method.apply(obj, arguments);
	      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
	      return result(this, obj);
	    };
	  });
	
	  // Add all accessor Array functions to the wrapper.
	  _.each(['concat', 'join', 'slice'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      return result(this, method.apply(this._wrapped, arguments));
	    };
	  });
	
	  // Extracts the result from a wrapped and chained object.
	  _.prototype.value = function() {
	    return this._wrapped;
	  };
	
	  // Provide unwrapping proxy for some methods used in engine operations
	  // such as arithmetic and JSON stringification.
	  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
	
	  _.prototype.toString = function() {
	    return '' + this._wrapped;
	  };
	
	  // AMD registration happens at the end for compatibility with AMD loaders
	  // that may not enforce next-turn semantics on modules. Even though general
	  // practice for AMD registration is to be anonymous, underscore registers
	  // as a named module because, like jQuery, it is a base library that is
	  // popular enough to be bundled in a third party lib, but not be part of
	  // an AMD load request. Those cases could generate an error when an
	  // anonymous define() is called outside of a loader request.
	  if (true) {
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
	      return _;
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
	}.call(this));


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

	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery JavaScript Library v3.2.1
	 * https://jquery.com/
	 *
	 * Includes Sizzle.js
	 * https://sizzlejs.com/
	 *
	 * Copyright JS Foundation and other contributors
	 * Released under the MIT license
	 * https://jquery.org/license
	 *
	 * Date: 2017-03-20T18:59Z
	 */
	( function( global, factory ) {
	
		"use strict";
	
		if ( typeof module === "object" && typeof module.exports === "object" ) {
	
			// For CommonJS and CommonJS-like environments where a proper `window`
			// is present, execute the factory and get jQuery.
			// For environments that do not have a `window` with a `document`
			// (such as Node.js), expose a factory as module.exports.
			// This accentuates the need for the creation of a real `window`.
			// e.g. var jQuery = require("jquery")(window);
			// See ticket #14549 for more info.
			module.exports = global.document ?
				factory( global, true ) :
				function( w ) {
					if ( !w.document ) {
						throw new Error( "jQuery requires a window with a document" );
					}
					return factory( w );
				};
		} else {
			factory( global );
		}
	
	// Pass this if window is not defined yet
	} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
	
	// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
	// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
	// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
	// enough that all such attempts are guarded in a try block.
	"use strict";
	
	var arr = [];
	
	var document = window.document;
	
	var getProto = Object.getPrototypeOf;
	
	var slice = arr.slice;
	
	var concat = arr.concat;
	
	var push = arr.push;
	
	var indexOf = arr.indexOf;
	
	var class2type = {};
	
	var toString = class2type.toString;
	
	var hasOwn = class2type.hasOwnProperty;
	
	var fnToString = hasOwn.toString;
	
	var ObjectFunctionString = fnToString.call( Object );
	
	var support = {};
	
	
	
		function DOMEval( code, doc ) {
			doc = doc || document;
	
			var script = doc.createElement( "script" );
	
			script.text = code;
			doc.head.appendChild( script ).parentNode.removeChild( script );
		}
	/* global Symbol */
	// Defining this global in .eslintrc.json would create a danger of using the global
	// unguarded in another place, it seems safer to define global only for this module
	
	
	
	var
		version = "3.2.1",
	
		// Define a local copy of jQuery
		jQuery = function( selector, context ) {
	
			// The jQuery object is actually just the init constructor 'enhanced'
			// Need init if jQuery is called (just allow error to be thrown if not included)
			return new jQuery.fn.init( selector, context );
		},
	
		// Support: Android <=4.0 only
		// Make sure we trim BOM and NBSP
		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
	
		// Matches dashed string for camelizing
		rmsPrefix = /^-ms-/,
		rdashAlpha = /-([a-z])/g,
	
		// Used by jQuery.camelCase as callback to replace()
		fcamelCase = function( all, letter ) {
			return letter.toUpperCase();
		};
	
	jQuery.fn = jQuery.prototype = {
	
		// The current version of jQuery being used
		jquery: version,
	
		constructor: jQuery,
	
		// The default length of a jQuery object is 0
		length: 0,
	
		toArray: function() {
			return slice.call( this );
		},
	
		// Get the Nth element in the matched element set OR
		// Get the whole matched element set as a clean array
		get: function( num ) {
	
			// Return all the elements in a clean array
			if ( num == null ) {
				return slice.call( this );
			}
	
			// Return just the one element from the set
			return num < 0 ? this[ num + this.length ] : this[ num ];
		},
	
		// Take an array of elements and push it onto the stack
		// (returning the new matched element set)
		pushStack: function( elems ) {
	
			// Build a new jQuery matched element set
			var ret = jQuery.merge( this.constructor(), elems );
	
			// Add the old object onto the stack (as a reference)
			ret.prevObject = this;
	
			// Return the newly-formed element set
			return ret;
		},
	
		// Execute a callback for every element in the matched set.
		each: function( callback ) {
			return jQuery.each( this, callback );
		},
	
		map: function( callback ) {
			return this.pushStack( jQuery.map( this, function( elem, i ) {
				return callback.call( elem, i, elem );
			} ) );
		},
	
		slice: function() {
			return this.pushStack( slice.apply( this, arguments ) );
		},
	
		first: function() {
			return this.eq( 0 );
		},
	
		last: function() {
			return this.eq( -1 );
		},
	
		eq: function( i ) {
			var len = this.length,
				j = +i + ( i < 0 ? len : 0 );
			return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
		},
	
		end: function() {
			return this.prevObject || this.constructor();
		},
	
		// For internal use only.
		// Behaves like an Array's method, not like a jQuery method.
		push: push,
		sort: arr.sort,
		splice: arr.splice
	};
	
	jQuery.extend = jQuery.fn.extend = function() {
		var options, name, src, copy, copyIsArray, clone,
			target = arguments[ 0 ] || {},
			i = 1,
			length = arguments.length,
			deep = false;
	
		// Handle a deep copy situation
		if ( typeof target === "boolean" ) {
			deep = target;
	
			// Skip the boolean and the target
			target = arguments[ i ] || {};
			i++;
		}
	
		// Handle case when target is a string or something (possible in deep copy)
		if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
			target = {};
		}
	
		// Extend jQuery itself if only one argument is passed
		if ( i === length ) {
			target = this;
			i--;
		}
	
		for ( ; i < length; i++ ) {
	
			// Only deal with non-null/undefined values
			if ( ( options = arguments[ i ] ) != null ) {
	
				// Extend the base object
				for ( name in options ) {
					src = target[ name ];
					copy = options[ name ];
	
					// Prevent never-ending loop
					if ( target === copy ) {
						continue;
					}
	
					// Recurse if we're merging plain objects or arrays
					if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
						( copyIsArray = Array.isArray( copy ) ) ) ) {
	
						if ( copyIsArray ) {
							copyIsArray = false;
							clone = src && Array.isArray( src ) ? src : [];
	
						} else {
							clone = src && jQuery.isPlainObject( src ) ? src : {};
						}
	
						// Never move original objects, clone them
						target[ name ] = jQuery.extend( deep, clone, copy );
	
					// Don't bring in undefined values
					} else if ( copy !== undefined ) {
						target[ name ] = copy;
					}
				}
			}
		}
	
		// Return the modified object
		return target;
	};
	
	jQuery.extend( {
	
		// Unique for each copy of jQuery on the page
		expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
	
		// Assume jQuery is ready without the ready module
		isReady: true,
	
		error: function( msg ) {
			throw new Error( msg );
		},
	
		noop: function() {},
	
		isFunction: function( obj ) {
			return jQuery.type( obj ) === "function";
		},
	
		isWindow: function( obj ) {
			return obj != null && obj === obj.window;
		},
	
		isNumeric: function( obj ) {
	
			// As of jQuery 3.0, isNumeric is limited to
			// strings and numbers (primitives or objects)
			// that can be coerced to finite numbers (gh-2662)
			var type = jQuery.type( obj );
			return ( type === "number" || type === "string" ) &&
	
				// parseFloat NaNs numeric-cast false positives ("")
				// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
				// subtraction forces infinities to NaN
				!isNaN( obj - parseFloat( obj ) );
		},
	
		isPlainObject: function( obj ) {
			var proto, Ctor;
	
			// Detect obvious negatives
			// Use toString instead of jQuery.type to catch host objects
			if ( !obj || toString.call( obj ) !== "[object Object]" ) {
				return false;
			}
	
			proto = getProto( obj );
	
			// Objects with no prototype (e.g., `Object.create( null )`) are plain
			if ( !proto ) {
				return true;
			}
	
			// Objects with prototype are plain iff they were constructed by a global Object function
			Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
			return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
		},
	
		isEmptyObject: function( obj ) {
	
			/* eslint-disable no-unused-vars */
			// See https://github.com/eslint/eslint/issues/6125
			var name;
	
			for ( name in obj ) {
				return false;
			}
			return true;
		},
	
		type: function( obj ) {
			if ( obj == null ) {
				return obj + "";
			}
	
			// Support: Android <=2.3 only (functionish RegExp)
			return typeof obj === "object" || typeof obj === "function" ?
				class2type[ toString.call( obj ) ] || "object" :
				typeof obj;
		},
	
		// Evaluates a script in a global context
		globalEval: function( code ) {
			DOMEval( code );
		},
	
		// Convert dashed to camelCase; used by the css and data modules
		// Support: IE <=9 - 11, Edge 12 - 13
		// Microsoft forgot to hump their vendor prefix (#9572)
		camelCase: function( string ) {
			return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
		},
	
		each: function( obj, callback ) {
			var length, i = 0;
	
			if ( isArrayLike( obj ) ) {
				length = obj.length;
				for ( ; i < length; i++ ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			}
	
			return obj;
		},
	
		// Support: Android <=4.0 only
		trim: function( text ) {
			return text == null ?
				"" :
				( text + "" ).replace( rtrim, "" );
		},
	
		// results is for internal usage only
		makeArray: function( arr, results ) {
			var ret = results || [];
	
			if ( arr != null ) {
				if ( isArrayLike( Object( arr ) ) ) {
					jQuery.merge( ret,
						typeof arr === "string" ?
						[ arr ] : arr
					);
				} else {
					push.call( ret, arr );
				}
			}
	
			return ret;
		},
	
		inArray: function( elem, arr, i ) {
			return arr == null ? -1 : indexOf.call( arr, elem, i );
		},
	
		// Support: Android <=4.0 only, PhantomJS 1 only
		// push.apply(_, arraylike) throws on ancient WebKit
		merge: function( first, second ) {
			var len = +second.length,
				j = 0,
				i = first.length;
	
			for ( ; j < len; j++ ) {
				first[ i++ ] = second[ j ];
			}
	
			first.length = i;
	
			return first;
		},
	
		grep: function( elems, callback, invert ) {
			var callbackInverse,
				matches = [],
				i = 0,
				length = elems.length,
				callbackExpect = !invert;
	
			// Go through the array, only saving the items
			// that pass the validator function
			for ( ; i < length; i++ ) {
				callbackInverse = !callback( elems[ i ], i );
				if ( callbackInverse !== callbackExpect ) {
					matches.push( elems[ i ] );
				}
			}
	
			return matches;
		},
	
		// arg is for internal usage only
		map: function( elems, callback, arg ) {
			var length, value,
				i = 0,
				ret = [];
	
			// Go through the array, translating each of the items to their new values
			if ( isArrayLike( elems ) ) {
				length = elems.length;
				for ( ; i < length; i++ ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
	
			// Go through every key on the object,
			} else {
				for ( i in elems ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
			}
	
			// Flatten any nested arrays
			return concat.apply( [], ret );
		},
	
		// A global GUID counter for objects
		guid: 1,
	
		// Bind a function to a context, optionally partially applying any
		// arguments.
		proxy: function( fn, context ) {
			var tmp, args, proxy;
	
			if ( typeof context === "string" ) {
				tmp = fn[ context ];
				context = fn;
				fn = tmp;
			}
	
			// Quick check to determine if target is callable, in the spec
			// this throws a TypeError, but we will just return undefined.
			if ( !jQuery.isFunction( fn ) ) {
				return undefined;
			}
	
			// Simulated bind
			args = slice.call( arguments, 2 );
			proxy = function() {
				return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
			};
	
			// Set the guid of unique handler to the same of original handler, so it can be removed
			proxy.guid = fn.guid = fn.guid || jQuery.guid++;
	
			return proxy;
		},
	
		now: Date.now,
	
		// jQuery.support is not used in Core but other projects attach their
		// properties to it so it needs to exist.
		support: support
	} );
	
	if ( typeof Symbol === "function" ) {
		jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
	}
	
	// Populate the class2type map
	jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
	function( i, name ) {
		class2type[ "[object " + name + "]" ] = name.toLowerCase();
	} );
	
	function isArrayLike( obj ) {
	
		// Support: real iOS 8.2 only (not reproducible in simulator)
		// `in` check used to prevent JIT error (gh-2145)
		// hasOwn isn't used here due to false negatives
		// regarding Nodelist length in IE
		var length = !!obj && "length" in obj && obj.length,
			type = jQuery.type( obj );
	
		if ( type === "function" || jQuery.isWindow( obj ) ) {
			return false;
		}
	
		return type === "array" || length === 0 ||
			typeof length === "number" && length > 0 && ( length - 1 ) in obj;
	}
	var Sizzle =
	/*!
	 * Sizzle CSS Selector Engine v2.3.3
	 * https://sizzlejs.com/
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license
	 * http://jquery.org/license
	 *
	 * Date: 2016-08-08
	 */
	(function( window ) {
	
	var i,
		support,
		Expr,
		getText,
		isXML,
		tokenize,
		compile,
		select,
		outermostContext,
		sortInput,
		hasDuplicate,
	
		// Local document vars
		setDocument,
		document,
		docElem,
		documentIsHTML,
		rbuggyQSA,
		rbuggyMatches,
		matches,
		contains,
	
		// Instance-specific data
		expando = "sizzle" + 1 * new Date(),
		preferredDoc = window.document,
		dirruns = 0,
		done = 0,
		classCache = createCache(),
		tokenCache = createCache(),
		compilerCache = createCache(),
		sortOrder = function( a, b ) {
			if ( a === b ) {
				hasDuplicate = true;
			}
			return 0;
		},
	
		// Instance methods
		hasOwn = ({}).hasOwnProperty,
		arr = [],
		pop = arr.pop,
		push_native = arr.push,
		push = arr.push,
		slice = arr.slice,
		// Use a stripped-down indexOf as it's faster than native
		// https://jsperf.com/thor-indexof-vs-for/5
		indexOf = function( list, elem ) {
			var i = 0,
				len = list.length;
			for ( ; i < len; i++ ) {
				if ( list[i] === elem ) {
					return i;
				}
			}
			return -1;
		},
	
		booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
	
		// Regular expressions
	
		// http://www.w3.org/TR/css3-selectors/#whitespace
		whitespace = "[\\x20\\t\\r\\n\\f]",
	
		// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
		identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
	
		// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
		attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
			// Operator (capture 2)
			"*([*^$|!~]?=)" + whitespace +
			// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
			"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
			"*\\]",
	
		pseudos = ":(" + identifier + ")(?:\\((" +
			// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
			// 1. quoted (capture 3; capture 4 or capture 5)
			"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
			// 2. simple (capture 6)
			"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
			// 3. anything else (capture 2)
			".*" +
			")\\)|)",
	
		// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
		rwhitespace = new RegExp( whitespace + "+", "g" ),
		rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
	
		rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
		rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
	
		rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
	
		rpseudo = new RegExp( pseudos ),
		ridentifier = new RegExp( "^" + identifier + "$" ),
	
		matchExpr = {
			"ID": new RegExp( "^#(" + identifier + ")" ),
			"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
			"TAG": new RegExp( "^(" + identifier + "|[*])" ),
			"ATTR": new RegExp( "^" + attributes ),
			"PSEUDO": new RegExp( "^" + pseudos ),
			"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
				"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
				"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
			"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
			// For use in libraries implementing .is()
			// We use this for POS matching in `select`
			"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
				whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
		},
	
		rinputs = /^(?:input|select|textarea|button)$/i,
		rheader = /^h\d$/i,
	
		rnative = /^[^{]+\{\s*\[native \w/,
	
		// Easily-parseable/retrievable ID or TAG or CLASS selectors
		rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
	
		rsibling = /[+~]/,
	
		// CSS escapes
		// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
		runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
		funescape = function( _, escaped, escapedWhitespace ) {
			var high = "0x" + escaped - 0x10000;
			// NaN means non-codepoint
			// Support: Firefox<24
			// Workaround erroneous numeric interpretation of +"0x"
			return high !== high || escapedWhitespace ?
				escaped :
				high < 0 ?
					// BMP codepoint
					String.fromCharCode( high + 0x10000 ) :
					// Supplemental Plane codepoint (surrogate pair)
					String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
		},
	
		// CSS string/identifier serialization
		// https://drafts.csswg.org/cssom/#common-serializing-idioms
		rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
		fcssescape = function( ch, asCodePoint ) {
			if ( asCodePoint ) {
	
				// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
				if ( ch === "\0" ) {
					return "\uFFFD";
				}
	
				// Control characters and (dependent upon position) numbers get escaped as code points
				return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
			}
	
			// Other potentially-special ASCII characters get backslash-escaped
			return "\\" + ch;
		},
	
		// Used for iframes
		// See setDocument()
		// Removing the function wrapper causes a "Permission Denied"
		// error in IE
		unloadHandler = function() {
			setDocument();
		},
	
		disabledAncestor = addCombinator(
			function( elem ) {
				return elem.disabled === true && ("form" in elem || "label" in elem);
			},
			{ dir: "parentNode", next: "legend" }
		);
	
	// Optimize for push.apply( _, NodeList )
	try {
		push.apply(
			(arr = slice.call( preferredDoc.childNodes )),
			preferredDoc.childNodes
		);
		// Support: Android<4.0
		// Detect silently failing push.apply
		arr[ preferredDoc.childNodes.length ].nodeType;
	} catch ( e ) {
		push = { apply: arr.length ?
	
			// Leverage slice if possible
			function( target, els ) {
				push_native.apply( target, slice.call(els) );
			} :
	
			// Support: IE<9
			// Otherwise append directly
			function( target, els ) {
				var j = target.length,
					i = 0;
				// Can't trust NodeList.length
				while ( (target[j++] = els[i++]) ) {}
				target.length = j - 1;
			}
		};
	}
	
	function Sizzle( selector, context, results, seed ) {
		var m, i, elem, nid, match, groups, newSelector,
			newContext = context && context.ownerDocument,
	
			// nodeType defaults to 9, since context defaults to document
			nodeType = context ? context.nodeType : 9;
	
		results = results || [];
	
		// Return early from calls with invalid selector or context
		if ( typeof selector !== "string" || !selector ||
			nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
	
			return results;
		}
	
		// Try to shortcut find operations (as opposed to filters) in HTML documents
		if ( !seed ) {
	
			if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
				setDocument( context );
			}
			context = context || document;
	
			if ( documentIsHTML ) {
	
				// If the selector is sufficiently simple, try using a "get*By*" DOM method
				// (excepting DocumentFragment context, where the methods don't exist)
				if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
	
					// ID selector
					if ( (m = match[1]) ) {
	
						// Document context
						if ( nodeType === 9 ) {
							if ( (elem = context.getElementById( m )) ) {
	
								// Support: IE, Opera, Webkit
								// TODO: identify versions
								// getElementById can match elements by name instead of ID
								if ( elem.id === m ) {
									results.push( elem );
									return results;
								}
							} else {
								return results;
							}
	
						// Element context
						} else {
	
							// Support: IE, Opera, Webkit
							// TODO: identify versions
							// getElementById can match elements by name instead of ID
							if ( newContext && (elem = newContext.getElementById( m )) &&
								contains( context, elem ) &&
								elem.id === m ) {
	
								results.push( elem );
								return results;
							}
						}
	
					// Type selector
					} else if ( match[2] ) {
						push.apply( results, context.getElementsByTagName( selector ) );
						return results;
	
					// Class selector
					} else if ( (m = match[3]) && support.getElementsByClassName &&
						context.getElementsByClassName ) {
	
						push.apply( results, context.getElementsByClassName( m ) );
						return results;
					}
				}
	
				// Take advantage of querySelectorAll
				if ( support.qsa &&
					!compilerCache[ selector + " " ] &&
					(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
	
					if ( nodeType !== 1 ) {
						newContext = context;
						newSelector = selector;
	
					// qSA looks outside Element context, which is not what we want
					// Thanks to Andrew Dupont for this workaround technique
					// Support: IE <=8
					// Exclude object elements
					} else if ( context.nodeName.toLowerCase() !== "object" ) {
	
						// Capture the context ID, setting it first if necessary
						if ( (nid = context.getAttribute( "id" )) ) {
							nid = nid.replace( rcssescape, fcssescape );
						} else {
							context.setAttribute( "id", (nid = expando) );
						}
	
						// Prefix every selector in the list
						groups = tokenize( selector );
						i = groups.length;
						while ( i-- ) {
							groups[i] = "#" + nid + " " + toSelector( groups[i] );
						}
						newSelector = groups.join( "," );
	
						// Expand context for sibling selectors
						newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
							context;
					}
	
					if ( newSelector ) {
						try {
							push.apply( results,
								newContext.querySelectorAll( newSelector )
							);
							return results;
						} catch ( qsaError ) {
						} finally {
							if ( nid === expando ) {
								context.removeAttribute( "id" );
							}
						}
					}
				}
			}
		}
	
		// All others
		return select( selector.replace( rtrim, "$1" ), context, results, seed );
	}
	
	/**
	 * Create key-value caches of limited size
	 * @returns {function(string, object)} Returns the Object data after storing it on itself with
	 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
	 *	deleting the oldest entry
	 */
	function createCache() {
		var keys = [];
	
		function cache( key, value ) {
			// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
			if ( keys.push( key + " " ) > Expr.cacheLength ) {
				// Only keep the most recent entries
				delete cache[ keys.shift() ];
			}
			return (cache[ key + " " ] = value);
		}
		return cache;
	}
	
	/**
	 * Mark a function for special use by Sizzle
	 * @param {Function} fn The function to mark
	 */
	function markFunction( fn ) {
		fn[ expando ] = true;
		return fn;
	}
	
	/**
	 * Support testing using an element
	 * @param {Function} fn Passed the created element and returns a boolean result
	 */
	function assert( fn ) {
		var el = document.createElement("fieldset");
	
		try {
			return !!fn( el );
		} catch (e) {
			return false;
		} finally {
			// Remove from its parent by default
			if ( el.parentNode ) {
				el.parentNode.removeChild( el );
			}
			// release memory in IE
			el = null;
		}
	}
	
	/**
	 * Adds the same handler for all of the specified attrs
	 * @param {String} attrs Pipe-separated list of attributes
	 * @param {Function} handler The method that will be applied
	 */
	function addHandle( attrs, handler ) {
		var arr = attrs.split("|"),
			i = arr.length;
	
		while ( i-- ) {
			Expr.attrHandle[ arr[i] ] = handler;
		}
	}
	
	/**
	 * Checks document order of two siblings
	 * @param {Element} a
	 * @param {Element} b
	 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
	 */
	function siblingCheck( a, b ) {
		var cur = b && a,
			diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
				a.sourceIndex - b.sourceIndex;
	
		// Use IE sourceIndex if available on both nodes
		if ( diff ) {
			return diff;
		}
	
		// Check if b follows a
		if ( cur ) {
			while ( (cur = cur.nextSibling) ) {
				if ( cur === b ) {
					return -1;
				}
			}
		}
	
		return a ? 1 : -1;
	}
	
	/**
	 * Returns a function to use in pseudos for input types
	 * @param {String} type
	 */
	function createInputPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return name === "input" && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for buttons
	 * @param {String} type
	 */
	function createButtonPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return (name === "input" || name === "button") && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for :enabled/:disabled
	 * @param {Boolean} disabled true for :disabled; false for :enabled
	 */
	function createDisabledPseudo( disabled ) {
	
		// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
		return function( elem ) {
	
			// Only certain elements can match :enabled or :disabled
			// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
			// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
			if ( "form" in elem ) {
	
				// Check for inherited disabledness on relevant non-disabled elements:
				// * listed form-associated elements in a disabled fieldset
				//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
				//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
				// * option elements in a disabled optgroup
				//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
				// All such elements have a "form" property.
				if ( elem.parentNode && elem.disabled === false ) {
	
					// Option elements defer to a parent optgroup if present
					if ( "label" in elem ) {
						if ( "label" in elem.parentNode ) {
							return elem.parentNode.disabled === disabled;
						} else {
							return elem.disabled === disabled;
						}
					}
	
					// Support: IE 6 - 11
					// Use the isDisabled shortcut property to check for disabled fieldset ancestors
					return elem.isDisabled === disabled ||
	
						// Where there is no isDisabled, check manually
						/* jshint -W018 */
						elem.isDisabled !== !disabled &&
							disabledAncestor( elem ) === disabled;
				}
	
				return elem.disabled === disabled;
	
			// Try to winnow out elements that can't be disabled before trusting the disabled property.
			// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
			// even exist on them, let alone have a boolean value.
			} else if ( "label" in elem ) {
				return elem.disabled === disabled;
			}
	
			// Remaining elements are neither :enabled nor :disabled
			return false;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for positionals
	 * @param {Function} fn
	 */
	function createPositionalPseudo( fn ) {
		return markFunction(function( argument ) {
			argument = +argument;
			return markFunction(function( seed, matches ) {
				var j,
					matchIndexes = fn( [], seed.length, argument ),
					i = matchIndexes.length;
	
				// Match elements found at the specified indexes
				while ( i-- ) {
					if ( seed[ (j = matchIndexes[i]) ] ) {
						seed[j] = !(matches[j] = seed[j]);
					}
				}
			});
		});
	}
	
	/**
	 * Checks a node for validity as a Sizzle context
	 * @param {Element|Object=} context
	 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
	 */
	function testContext( context ) {
		return context && typeof context.getElementsByTagName !== "undefined" && context;
	}
	
	// Expose support vars for convenience
	support = Sizzle.support = {};
	
	/**
	 * Detects XML nodes
	 * @param {Element|Object} elem An element or a document
	 * @returns {Boolean} True iff elem is a non-HTML XML node
	 */
	isXML = Sizzle.isXML = function( elem ) {
		// documentElement is verified for cases where it doesn't yet exist
		// (such as loading iframes in IE - #4833)
		var documentElement = elem && (elem.ownerDocument || elem).documentElement;
		return documentElement ? documentElement.nodeName !== "HTML" : false;
	};
	
	/**
	 * Sets document-related variables once based on the current document
	 * @param {Element|Object} [doc] An element or document object to use to set the document
	 * @returns {Object} Returns the current document
	 */
	setDocument = Sizzle.setDocument = function( node ) {
		var hasCompare, subWindow,
			doc = node ? node.ownerDocument || node : preferredDoc;
	
		// Return early if doc is invalid or already selected
		if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
			return document;
		}
	
		// Update global variables
		document = doc;
		docElem = document.documentElement;
		documentIsHTML = !isXML( document );
	
		// Support: IE 9-11, Edge
		// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
		if ( preferredDoc !== document &&
			(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
	
			// Support: IE 11, Edge
			if ( subWindow.addEventListener ) {
				subWindow.addEventListener( "unload", unloadHandler, false );
	
			// Support: IE 9 - 10 only
			} else if ( subWindow.attachEvent ) {
				subWindow.attachEvent( "onunload", unloadHandler );
			}
		}
	
		/* Attributes
		---------------------------------------------------------------------- */
	
		// Support: IE<8
		// Verify that getAttribute really returns attributes and not properties
		// (excepting IE8 booleans)
		support.attributes = assert(function( el ) {
			el.className = "i";
			return !el.getAttribute("className");
		});
	
		/* getElement(s)By*
		---------------------------------------------------------------------- */
	
		// Check if getElementsByTagName("*") returns only elements
		support.getElementsByTagName = assert(function( el ) {
			el.appendChild( document.createComment("") );
			return !el.getElementsByTagName("*").length;
		});
	
		// Support: IE<9
		support.getElementsByClassName = rnative.test( document.getElementsByClassName );
	
		// Support: IE<10
		// Check if getElementById returns elements by name
		// The broken getElementById methods don't pick up programmatically-set names,
		// so use a roundabout getElementsByName test
		support.getById = assert(function( el ) {
			docElem.appendChild( el ).id = expando;
			return !document.getElementsByName || !document.getElementsByName( expando ).length;
		});
	
		// ID filter and find
		if ( support.getById ) {
			Expr.filter["ID"] = function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					return elem.getAttribute("id") === attrId;
				};
			};
			Expr.find["ID"] = function( id, context ) {
				if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
					var elem = context.getElementById( id );
					return elem ? [ elem ] : [];
				}
			};
		} else {
			Expr.filter["ID"] =  function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					var node = typeof elem.getAttributeNode !== "undefined" &&
						elem.getAttributeNode("id");
					return node && node.value === attrId;
				};
			};
	
			// Support: IE 6 - 7 only
			// getElementById is not reliable as a find shortcut
			Expr.find["ID"] = function( id, context ) {
				if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
					var node, i, elems,
						elem = context.getElementById( id );
	
					if ( elem ) {
	
						// Verify the id attribute
						node = elem.getAttributeNode("id");
						if ( node && node.value === id ) {
							return [ elem ];
						}
	
						// Fall back on getElementsByName
						elems = context.getElementsByName( id );
						i = 0;
						while ( (elem = elems[i++]) ) {
							node = elem.getAttributeNode("id");
							if ( node && node.value === id ) {
								return [ elem ];
							}
						}
					}
	
					return [];
				}
			};
		}
	
		// Tag
		Expr.find["TAG"] = support.getElementsByTagName ?
			function( tag, context ) {
				if ( typeof context.getElementsByTagName !== "undefined" ) {
					return context.getElementsByTagName( tag );
	
				// DocumentFragment nodes don't have gEBTN
				} else if ( support.qsa ) {
					return context.querySelectorAll( tag );
				}
			} :
	
			function( tag, context ) {
				var elem,
					tmp = [],
					i = 0,
					// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
					results = context.getElementsByTagName( tag );
	
				// Filter out possible comments
				if ( tag === "*" ) {
					while ( (elem = results[i++]) ) {
						if ( elem.nodeType === 1 ) {
							tmp.push( elem );
						}
					}
	
					return tmp;
				}
				return results;
			};
	
		// Class
		Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
			if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
				return context.getElementsByClassName( className );
			}
		};
	
		/* QSA/matchesSelector
		---------------------------------------------------------------------- */
	
		// QSA and matchesSelector support
	
		// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
		rbuggyMatches = [];
	
		// qSa(:focus) reports false when true (Chrome 21)
		// We allow this because of a bug in IE8/9 that throws an error
		// whenever `document.activeElement` is accessed on an iframe
		// So, we allow :focus to pass through QSA all the time to avoid the IE error
		// See https://bugs.jquery.com/ticket/13378
		rbuggyQSA = [];
	
		if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
			// Build QSA regex
			// Regex strategy adopted from Diego Perini
			assert(function( el ) {
				// Select is set to empty string on purpose
				// This is to test IE's treatment of not explicitly
				// setting a boolean content attribute,
				// since its presence should be enough
				// https://bugs.jquery.com/ticket/12359
				docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
					"<select id='" + expando + "-\r\\' msallowcapture=''>" +
					"<option selected=''></option></select>";
	
				// Support: IE8, Opera 11-12.16
				// Nothing should be selected when empty strings follow ^= or $= or *=
				// The test attribute must be unknown in Opera but "safe" for WinRT
				// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
				if ( el.querySelectorAll("[msallowcapture^='']").length ) {
					rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
				}
	
				// Support: IE8
				// Boolean attributes and "value" are not treated correctly
				if ( !el.querySelectorAll("[selected]").length ) {
					rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
				}
	
				// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
				if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
					rbuggyQSA.push("~=");
				}
	
				// Webkit/Opera - :checked should return selected option elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				// IE8 throws error here and will not see later tests
				if ( !el.querySelectorAll(":checked").length ) {
					rbuggyQSA.push(":checked");
				}
	
				// Support: Safari 8+, iOS 8+
				// https://bugs.webkit.org/show_bug.cgi?id=136851
				// In-page `selector#id sibling-combinator selector` fails
				if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
					rbuggyQSA.push(".#.+[+~]");
				}
			});
	
			assert(function( el ) {
				el.innerHTML = "<a href='' disabled='disabled'></a>" +
					"<select disabled='disabled'><option/></select>";
	
				// Support: Windows 8 Native Apps
				// The type and name attributes are restricted during .innerHTML assignment
				var input = document.createElement("input");
				input.setAttribute( "type", "hidden" );
				el.appendChild( input ).setAttribute( "name", "D" );
	
				// Support: IE8
				// Enforce case-sensitivity of name attribute
				if ( el.querySelectorAll("[name=d]").length ) {
					rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
				}
	
				// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
				// IE8 throws error here and will not see later tests
				if ( el.querySelectorAll(":enabled").length !== 2 ) {
					rbuggyQSA.push( ":enabled", ":disabled" );
				}
	
				// Support: IE9-11+
				// IE's :disabled selector does not pick up the children of disabled fieldsets
				docElem.appendChild( el ).disabled = true;
				if ( el.querySelectorAll(":disabled").length !== 2 ) {
					rbuggyQSA.push( ":enabled", ":disabled" );
				}
	
				// Opera 10-11 does not throw on post-comma invalid pseudos
				el.querySelectorAll("*,:x");
				rbuggyQSA.push(",.*:");
			});
		}
	
		if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
			docElem.webkitMatchesSelector ||
			docElem.mozMatchesSelector ||
			docElem.oMatchesSelector ||
			docElem.msMatchesSelector) )) ) {
	
			assert(function( el ) {
				// Check to see if it's possible to do matchesSelector
				// on a disconnected node (IE 9)
				support.disconnectedMatch = matches.call( el, "*" );
	
				// This should fail with an exception
				// Gecko does not error, returns false instead
				matches.call( el, "[s!='']:x" );
				rbuggyMatches.push( "!=", pseudos );
			});
		}
	
		rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
		rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
	
		/* Contains
		---------------------------------------------------------------------- */
		hasCompare = rnative.test( docElem.compareDocumentPosition );
	
		// Element contains another
		// Purposefully self-exclusive
		// As in, an element does not contain itself
		contains = hasCompare || rnative.test( docElem.contains ) ?
			function( a, b ) {
				var adown = a.nodeType === 9 ? a.documentElement : a,
					bup = b && b.parentNode;
				return a === bup || !!( bup && bup.nodeType === 1 && (
					adown.contains ?
						adown.contains( bup ) :
						a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
				));
			} :
			function( a, b ) {
				if ( b ) {
					while ( (b = b.parentNode) ) {
						if ( b === a ) {
							return true;
						}
					}
				}
				return false;
			};
	
		/* Sorting
		---------------------------------------------------------------------- */
	
		// Document order sorting
		sortOrder = hasCompare ?
		function( a, b ) {
	
			// Flag for duplicate removal
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			// Sort on method existence if only one input has compareDocumentPosition
			var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
			if ( compare ) {
				return compare;
			}
	
			// Calculate position if both inputs belong to the same document
			compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
				a.compareDocumentPosition( b ) :
	
				// Otherwise we know they are disconnected
				1;
	
			// Disconnected nodes
			if ( compare & 1 ||
				(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
	
				// Choose the first element that is related to our preferred document
				if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
					return -1;
				}
				if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
					return 1;
				}
	
				// Maintain original order
				return sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
			}
	
			return compare & 4 ? -1 : 1;
		} :
		function( a, b ) {
			// Exit early if the nodes are identical
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			var cur,
				i = 0,
				aup = a.parentNode,
				bup = b.parentNode,
				ap = [ a ],
				bp = [ b ];
	
			// Parentless nodes are either documents or disconnected
			if ( !aup || !bup ) {
				return a === document ? -1 :
					b === document ? 1 :
					aup ? -1 :
					bup ? 1 :
					sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
	
			// If the nodes are siblings, we can do a quick check
			} else if ( aup === bup ) {
				return siblingCheck( a, b );
			}
	
			// Otherwise we need full lists of their ancestors for comparison
			cur = a;
			while ( (cur = cur.parentNode) ) {
				ap.unshift( cur );
			}
			cur = b;
			while ( (cur = cur.parentNode) ) {
				bp.unshift( cur );
			}
	
			// Walk down the tree looking for a discrepancy
			while ( ap[i] === bp[i] ) {
				i++;
			}
	
			return i ?
				// Do a sibling check if the nodes have a common ancestor
				siblingCheck( ap[i], bp[i] ) :
	
				// Otherwise nodes in our document sort first
				ap[i] === preferredDoc ? -1 :
				bp[i] === preferredDoc ? 1 :
				0;
		};
	
		return document;
	};
	
	Sizzle.matches = function( expr, elements ) {
		return Sizzle( expr, null, null, elements );
	};
	
	Sizzle.matchesSelector = function( elem, expr ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		// Make sure that attribute selectors are quoted
		expr = expr.replace( rattributeQuotes, "='$1']" );
	
		if ( support.matchesSelector && documentIsHTML &&
			!compilerCache[ expr + " " ] &&
			( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
			( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
	
			try {
				var ret = matches.call( elem, expr );
	
				// IE 9's matchesSelector returns false on disconnected nodes
				if ( ret || support.disconnectedMatch ||
						// As well, disconnected nodes are said to be in a document
						// fragment in IE 9
						elem.document && elem.document.nodeType !== 11 ) {
					return ret;
				}
			} catch (e) {}
		}
	
		return Sizzle( expr, document, null, [ elem ] ).length > 0;
	};
	
	Sizzle.contains = function( context, elem ) {
		// Set document vars if needed
		if ( ( context.ownerDocument || context ) !== document ) {
			setDocument( context );
		}
		return contains( context, elem );
	};
	
	Sizzle.attr = function( elem, name ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		var fn = Expr.attrHandle[ name.toLowerCase() ],
			// Don't get fooled by Object.prototype properties (jQuery #13807)
			val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
				fn( elem, name, !documentIsHTML ) :
				undefined;
	
		return val !== undefined ?
			val :
			support.attributes || !documentIsHTML ?
				elem.getAttribute( name ) :
				(val = elem.getAttributeNode(name)) && val.specified ?
					val.value :
					null;
	};
	
	Sizzle.escape = function( sel ) {
		return (sel + "").replace( rcssescape, fcssescape );
	};
	
	Sizzle.error = function( msg ) {
		throw new Error( "Syntax error, unrecognized expression: " + msg );
	};
	
	/**
	 * Document sorting and removing duplicates
	 * @param {ArrayLike} results
	 */
	Sizzle.uniqueSort = function( results ) {
		var elem,
			duplicates = [],
			j = 0,
			i = 0;
	
		// Unless we *know* we can detect duplicates, assume their presence
		hasDuplicate = !support.detectDuplicates;
		sortInput = !support.sortStable && results.slice( 0 );
		results.sort( sortOrder );
	
		if ( hasDuplicate ) {
			while ( (elem = results[i++]) ) {
				if ( elem === results[ i ] ) {
					j = duplicates.push( i );
				}
			}
			while ( j-- ) {
				results.splice( duplicates[ j ], 1 );
			}
		}
	
		// Clear input after sorting to release objects
		// See https://github.com/jquery/sizzle/pull/225
		sortInput = null;
	
		return results;
	};
	
	/**
	 * Utility function for retrieving the text value of an array of DOM nodes
	 * @param {Array|Element} elem
	 */
	getText = Sizzle.getText = function( elem ) {
		var node,
			ret = "",
			i = 0,
			nodeType = elem.nodeType;
	
		if ( !nodeType ) {
			// If no nodeType, this is expected to be an array
			while ( (node = elem[i++]) ) {
				// Do not traverse comment nodes
				ret += getText( node );
			}
		} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
			// Use textContent for elements
			// innerText usage removed for consistency of new lines (jQuery #11153)
			if ( typeof elem.textContent === "string" ) {
				return elem.textContent;
			} else {
				// Traverse its children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					ret += getText( elem );
				}
			}
		} else if ( nodeType === 3 || nodeType === 4 ) {
			return elem.nodeValue;
		}
		// Do not include comment or processing instruction nodes
	
		return ret;
	};
	
	Expr = Sizzle.selectors = {
	
		// Can be adjusted by the user
		cacheLength: 50,
	
		createPseudo: markFunction,
	
		match: matchExpr,
	
		attrHandle: {},
	
		find: {},
	
		relative: {
			">": { dir: "parentNode", first: true },
			" ": { dir: "parentNode" },
			"+": { dir: "previousSibling", first: true },
			"~": { dir: "previousSibling" }
		},
	
		preFilter: {
			"ATTR": function( match ) {
				match[1] = match[1].replace( runescape, funescape );
	
				// Move the given value to match[3] whether quoted or unquoted
				match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
	
				if ( match[2] === "~=" ) {
					match[3] = " " + match[3] + " ";
				}
	
				return match.slice( 0, 4 );
			},
	
			"CHILD": function( match ) {
				/* matches from matchExpr["CHILD"]
					1 type (only|nth|...)
					2 what (child|of-type)
					3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
					4 xn-component of xn+y argument ([+-]?\d*n|)
					5 sign of xn-component
					6 x of xn-component
					7 sign of y-component
					8 y of y-component
				*/
				match[1] = match[1].toLowerCase();
	
				if ( match[1].slice( 0, 3 ) === "nth" ) {
					// nth-* requires argument
					if ( !match[3] ) {
						Sizzle.error( match[0] );
					}
	
					// numeric x and y parameters for Expr.filter.CHILD
					// remember that false/true cast respectively to 0/1
					match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
					match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
	
				// other types prohibit arguments
				} else if ( match[3] ) {
					Sizzle.error( match[0] );
				}
	
				return match;
			},
	
			"PSEUDO": function( match ) {
				var excess,
					unquoted = !match[6] && match[2];
	
				if ( matchExpr["CHILD"].test( match[0] ) ) {
					return null;
				}
	
				// Accept quoted arguments as-is
				if ( match[3] ) {
					match[2] = match[4] || match[5] || "";
	
				// Strip excess characters from unquoted arguments
				} else if ( unquoted && rpseudo.test( unquoted ) &&
					// Get excess from tokenize (recursively)
					(excess = tokenize( unquoted, true )) &&
					// advance to the next closing parenthesis
					(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
	
					// excess is a negative index
					match[0] = match[0].slice( 0, excess );
					match[2] = unquoted.slice( 0, excess );
				}
	
				// Return only captures needed by the pseudo filter method (type and argument)
				return match.slice( 0, 3 );
			}
		},
	
		filter: {
	
			"TAG": function( nodeNameSelector ) {
				var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
				return nodeNameSelector === "*" ?
					function() { return true; } :
					function( elem ) {
						return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
					};
			},
	
			"CLASS": function( className ) {
				var pattern = classCache[ className + " " ];
	
				return pattern ||
					(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
					classCache( className, function( elem ) {
						return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
					});
			},
	
			"ATTR": function( name, operator, check ) {
				return function( elem ) {
					var result = Sizzle.attr( elem, name );
	
					if ( result == null ) {
						return operator === "!=";
					}
					if ( !operator ) {
						return true;
					}
	
					result += "";
	
					return operator === "=" ? result === check :
						operator === "!=" ? result !== check :
						operator === "^=" ? check && result.indexOf( check ) === 0 :
						operator === "*=" ? check && result.indexOf( check ) > -1 :
						operator === "$=" ? check && result.slice( -check.length ) === check :
						operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
						operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
						false;
				};
			},
	
			"CHILD": function( type, what, argument, first, last ) {
				var simple = type.slice( 0, 3 ) !== "nth",
					forward = type.slice( -4 ) !== "last",
					ofType = what === "of-type";
	
				return first === 1 && last === 0 ?
	
					// Shortcut for :nth-*(n)
					function( elem ) {
						return !!elem.parentNode;
					} :
	
					function( elem, context, xml ) {
						var cache, uniqueCache, outerCache, node, nodeIndex, start,
							dir = simple !== forward ? "nextSibling" : "previousSibling",
							parent = elem.parentNode,
							name = ofType && elem.nodeName.toLowerCase(),
							useCache = !xml && !ofType,
							diff = false;
	
						if ( parent ) {
	
							// :(first|last|only)-(child|of-type)
							if ( simple ) {
								while ( dir ) {
									node = elem;
									while ( (node = node[ dir ]) ) {
										if ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) {
	
											return false;
										}
									}
									// Reverse direction for :only-* (if we haven't yet done so)
									start = dir = type === "only" && !start && "nextSibling";
								}
								return true;
							}
	
							start = [ forward ? parent.firstChild : parent.lastChild ];
	
							// non-xml :nth-child(...) stores cache data on `parent`
							if ( forward && useCache ) {
	
								// Seek `elem` from a previously-cached index
	
								// ...in a gzip-friendly way
								node = parent;
								outerCache = node[ expando ] || (node[ expando ] = {});
	
								// Support: IE <9 only
								// Defend against cloned attroperties (jQuery gh-1709)
								uniqueCache = outerCache[ node.uniqueID ] ||
									(outerCache[ node.uniqueID ] = {});
	
								cache = uniqueCache[ type ] || [];
								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
								diff = nodeIndex && cache[ 2 ];
								node = nodeIndex && parent.childNodes[ nodeIndex ];
	
								while ( (node = ++nodeIndex && node && node[ dir ] ||
	
									// Fallback to seeking `elem` from the start
									(diff = nodeIndex = 0) || start.pop()) ) {
	
									// When found, cache indexes on `parent` and break
									if ( node.nodeType === 1 && ++diff && node === elem ) {
										uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
										break;
									}
								}
	
							} else {
								// Use previously-cached element index if available
								if ( useCache ) {
									// ...in a gzip-friendly way
									node = elem;
									outerCache = node[ expando ] || (node[ expando ] = {});
	
									// Support: IE <9 only
									// Defend against cloned attroperties (jQuery gh-1709)
									uniqueCache = outerCache[ node.uniqueID ] ||
										(outerCache[ node.uniqueID ] = {});
	
									cache = uniqueCache[ type ] || [];
									nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
									diff = nodeIndex;
								}
	
								// xml :nth-child(...)
								// or :nth-last-child(...) or :nth(-last)?-of-type(...)
								if ( diff === false ) {
									// Use the same loop as above to seek `elem` from the start
									while ( (node = ++nodeIndex && node && node[ dir ] ||
										(diff = nodeIndex = 0) || start.pop()) ) {
	
										if ( ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) &&
											++diff ) {
	
											// Cache the index of each encountered element
											if ( useCache ) {
												outerCache = node[ expando ] || (node[ expando ] = {});
	
												// Support: IE <9 only
												// Defend against cloned attroperties (jQuery gh-1709)
												uniqueCache = outerCache[ node.uniqueID ] ||
													(outerCache[ node.uniqueID ] = {});
	
												uniqueCache[ type ] = [ dirruns, diff ];
											}
	
											if ( node === elem ) {
												break;
											}
										}
									}
								}
							}
	
							// Incorporate the offset, then check against cycle size
							diff -= last;
							return diff === first || ( diff % first === 0 && diff / first >= 0 );
						}
					};
			},
	
			"PSEUDO": function( pseudo, argument ) {
				// pseudo-class names are case-insensitive
				// http://www.w3.org/TR/selectors/#pseudo-classes
				// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
				// Remember that setFilters inherits from pseudos
				var args,
					fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
						Sizzle.error( "unsupported pseudo: " + pseudo );
	
				// The user may use createPseudo to indicate that
				// arguments are needed to create the filter function
				// just as Sizzle does
				if ( fn[ expando ] ) {
					return fn( argument );
				}
	
				// But maintain support for old signatures
				if ( fn.length > 1 ) {
					args = [ pseudo, pseudo, "", argument ];
					return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
						markFunction(function( seed, matches ) {
							var idx,
								matched = fn( seed, argument ),
								i = matched.length;
							while ( i-- ) {
								idx = indexOf( seed, matched[i] );
								seed[ idx ] = !( matches[ idx ] = matched[i] );
							}
						}) :
						function( elem ) {
							return fn( elem, 0, args );
						};
				}
	
				return fn;
			}
		},
	
		pseudos: {
			// Potentially complex pseudos
			"not": markFunction(function( selector ) {
				// Trim the selector passed to compile
				// to avoid treating leading and trailing
				// spaces as combinators
				var input = [],
					results = [],
					matcher = compile( selector.replace( rtrim, "$1" ) );
	
				return matcher[ expando ] ?
					markFunction(function( seed, matches, context, xml ) {
						var elem,
							unmatched = matcher( seed, null, xml, [] ),
							i = seed.length;
	
						// Match elements unmatched by `matcher`
						while ( i-- ) {
							if ( (elem = unmatched[i]) ) {
								seed[i] = !(matches[i] = elem);
							}
						}
					}) :
					function( elem, context, xml ) {
						input[0] = elem;
						matcher( input, null, xml, results );
						// Don't keep the element (issue #299)
						input[0] = null;
						return !results.pop();
					};
			}),
	
			"has": markFunction(function( selector ) {
				return function( elem ) {
					return Sizzle( selector, elem ).length > 0;
				};
			}),
	
			"contains": markFunction(function( text ) {
				text = text.replace( runescape, funescape );
				return function( elem ) {
					return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
				};
			}),
	
			// "Whether an element is represented by a :lang() selector
			// is based solely on the element's language value
			// being equal to the identifier C,
			// or beginning with the identifier C immediately followed by "-".
			// The matching of C against the element's language value is performed case-insensitively.
			// The identifier C does not have to be a valid language name."
			// http://www.w3.org/TR/selectors/#lang-pseudo
			"lang": markFunction( function( lang ) {
				// lang value must be a valid identifier
				if ( !ridentifier.test(lang || "") ) {
					Sizzle.error( "unsupported lang: " + lang );
				}
				lang = lang.replace( runescape, funescape ).toLowerCase();
				return function( elem ) {
					var elemLang;
					do {
						if ( (elemLang = documentIsHTML ?
							elem.lang :
							elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
	
							elemLang = elemLang.toLowerCase();
							return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
						}
					} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
					return false;
				};
			}),
	
			// Miscellaneous
			"target": function( elem ) {
				var hash = window.location && window.location.hash;
				return hash && hash.slice( 1 ) === elem.id;
			},
	
			"root": function( elem ) {
				return elem === docElem;
			},
	
			"focus": function( elem ) {
				return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
			},
	
			// Boolean properties
			"enabled": createDisabledPseudo( false ),
			"disabled": createDisabledPseudo( true ),
	
			"checked": function( elem ) {
				// In CSS3, :checked should return both checked and selected elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				var nodeName = elem.nodeName.toLowerCase();
				return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
			},
	
			"selected": function( elem ) {
				// Accessing this property makes selected-by-default
				// options in Safari work properly
				if ( elem.parentNode ) {
					elem.parentNode.selectedIndex;
				}
	
				return elem.selected === true;
			},
	
			// Contents
			"empty": function( elem ) {
				// http://www.w3.org/TR/selectors/#empty-pseudo
				// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
				//   but not by others (comment: 8; processing instruction: 7; etc.)
				// nodeType < 6 works because attributes (2) do not appear as children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					if ( elem.nodeType < 6 ) {
						return false;
					}
				}
				return true;
			},
	
			"parent": function( elem ) {
				return !Expr.pseudos["empty"]( elem );
			},
	
			// Element/input types
			"header": function( elem ) {
				return rheader.test( elem.nodeName );
			},
	
			"input": function( elem ) {
				return rinputs.test( elem.nodeName );
			},
	
			"button": function( elem ) {
				var name = elem.nodeName.toLowerCase();
				return name === "input" && elem.type === "button" || name === "button";
			},
	
			"text": function( elem ) {
				var attr;
				return elem.nodeName.toLowerCase() === "input" &&
					elem.type === "text" &&
	
					// Support: IE<8
					// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
					( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
			},
	
			// Position-in-collection
			"first": createPositionalPseudo(function() {
				return [ 0 ];
			}),
	
			"last": createPositionalPseudo(function( matchIndexes, length ) {
				return [ length - 1 ];
			}),
	
			"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
				return [ argument < 0 ? argument + length : argument ];
			}),
	
			"even": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 0;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"odd": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 1;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; --i >= 0; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; ++i < length; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			})
		}
	};
	
	Expr.pseudos["nth"] = Expr.pseudos["eq"];
	
	// Add button/input type pseudos
	for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
		Expr.pseudos[ i ] = createInputPseudo( i );
	}
	for ( i in { submit: true, reset: true } ) {
		Expr.pseudos[ i ] = createButtonPseudo( i );
	}
	
	// Easy API for creating new setFilters
	function setFilters() {}
	setFilters.prototype = Expr.filters = Expr.pseudos;
	Expr.setFilters = new setFilters();
	
	tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
		var matched, match, tokens, type,
			soFar, groups, preFilters,
			cached = tokenCache[ selector + " " ];
	
		if ( cached ) {
			return parseOnly ? 0 : cached.slice( 0 );
		}
	
		soFar = selector;
		groups = [];
		preFilters = Expr.preFilter;
	
		while ( soFar ) {
	
			// Comma and first run
			if ( !matched || (match = rcomma.exec( soFar )) ) {
				if ( match ) {
					// Don't consume trailing commas as valid
					soFar = soFar.slice( match[0].length ) || soFar;
				}
				groups.push( (tokens = []) );
			}
	
			matched = false;
	
			// Combinators
			if ( (match = rcombinators.exec( soFar )) ) {
				matched = match.shift();
				tokens.push({
					value: matched,
					// Cast descendant combinators to space
					type: match[0].replace( rtrim, " " )
				});
				soFar = soFar.slice( matched.length );
			}
	
			// Filters
			for ( type in Expr.filter ) {
				if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
					(match = preFilters[ type ]( match ))) ) {
					matched = match.shift();
					tokens.push({
						value: matched,
						type: type,
						matches: match
					});
					soFar = soFar.slice( matched.length );
				}
			}
	
			if ( !matched ) {
				break;
			}
		}
	
		// Return the length of the invalid excess
		// if we're just parsing
		// Otherwise, throw an error or return tokens
		return parseOnly ?
			soFar.length :
			soFar ?
				Sizzle.error( selector ) :
				// Cache the tokens
				tokenCache( selector, groups ).slice( 0 );
	};
	
	function toSelector( tokens ) {
		var i = 0,
			len = tokens.length,
			selector = "";
		for ( ; i < len; i++ ) {
			selector += tokens[i].value;
		}
		return selector;
	}
	
	function addCombinator( matcher, combinator, base ) {
		var dir = combinator.dir,
			skip = combinator.next,
			key = skip || dir,
			checkNonElements = base && key === "parentNode",
			doneName = done++;
	
		return combinator.first ?
			// Check against closest ancestor/preceding element
			function( elem, context, xml ) {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						return matcher( elem, context, xml );
					}
				}
				return false;
			} :
	
			// Check against all ancestor/preceding elements
			function( elem, context, xml ) {
				var oldCache, uniqueCache, outerCache,
					newCache = [ dirruns, doneName ];
	
				// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
				if ( xml ) {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							if ( matcher( elem, context, xml ) ) {
								return true;
							}
						}
					}
				} else {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							outerCache = elem[ expando ] || (elem[ expando ] = {});
	
							// Support: IE <9 only
							// Defend against cloned attroperties (jQuery gh-1709)
							uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
	
							if ( skip && skip === elem.nodeName.toLowerCase() ) {
								elem = elem[ dir ] || elem;
							} else if ( (oldCache = uniqueCache[ key ]) &&
								oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
	
								// Assign to newCache so results back-propagate to previous elements
								return (newCache[ 2 ] = oldCache[ 2 ]);
							} else {
								// Reuse newcache so results back-propagate to previous elements
								uniqueCache[ key ] = newCache;
	
								// A match means we're done; a fail means we have to keep checking
								if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
									return true;
								}
							}
						}
					}
				}
				return false;
			};
	}
	
	function elementMatcher( matchers ) {
		return matchers.length > 1 ?
			function( elem, context, xml ) {
				var i = matchers.length;
				while ( i-- ) {
					if ( !matchers[i]( elem, context, xml ) ) {
						return false;
					}
				}
				return true;
			} :
			matchers[0];
	}
	
	function multipleContexts( selector, contexts, results ) {
		var i = 0,
			len = contexts.length;
		for ( ; i < len; i++ ) {
			Sizzle( selector, contexts[i], results );
		}
		return results;
	}
	
	function condense( unmatched, map, filter, context, xml ) {
		var elem,
			newUnmatched = [],
			i = 0,
			len = unmatched.length,
			mapped = map != null;
	
		for ( ; i < len; i++ ) {
			if ( (elem = unmatched[i]) ) {
				if ( !filter || filter( elem, context, xml ) ) {
					newUnmatched.push( elem );
					if ( mapped ) {
						map.push( i );
					}
				}
			}
		}
	
		return newUnmatched;
	}
	
	function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
		if ( postFilter && !postFilter[ expando ] ) {
			postFilter = setMatcher( postFilter );
		}
		if ( postFinder && !postFinder[ expando ] ) {
			postFinder = setMatcher( postFinder, postSelector );
		}
		return markFunction(function( seed, results, context, xml ) {
			var temp, i, elem,
				preMap = [],
				postMap = [],
				preexisting = results.length,
	
				// Get initial elements from seed or context
				elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
	
				// Prefilter to get matcher input, preserving a map for seed-results synchronization
				matcherIn = preFilter && ( seed || !selector ) ?
					condense( elems, preMap, preFilter, context, xml ) :
					elems,
	
				matcherOut = matcher ?
					// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
					postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
	
						// ...intermediate processing is necessary
						[] :
	
						// ...otherwise use results directly
						results :
					matcherIn;
	
			// Find primary matches
			if ( matcher ) {
				matcher( matcherIn, matcherOut, context, xml );
			}
	
			// Apply postFilter
			if ( postFilter ) {
				temp = condense( matcherOut, postMap );
				postFilter( temp, [], context, xml );
	
				// Un-match failing elements by moving them back to matcherIn
				i = temp.length;
				while ( i-- ) {
					if ( (elem = temp[i]) ) {
						matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
					}
				}
			}
	
			if ( seed ) {
				if ( postFinder || preFilter ) {
					if ( postFinder ) {
						// Get the final matcherOut by condensing this intermediate into postFinder contexts
						temp = [];
						i = matcherOut.length;
						while ( i-- ) {
							if ( (elem = matcherOut[i]) ) {
								// Restore matcherIn since elem is not yet a final match
								temp.push( (matcherIn[i] = elem) );
							}
						}
						postFinder( null, (matcherOut = []), temp, xml );
					}
	
					// Move matched elements from seed to results to keep them synchronized
					i = matcherOut.length;
					while ( i-- ) {
						if ( (elem = matcherOut[i]) &&
							(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
	
							seed[temp] = !(results[temp] = elem);
						}
					}
				}
	
			// Add elements to results, through postFinder if defined
			} else {
				matcherOut = condense(
					matcherOut === results ?
						matcherOut.splice( preexisting, matcherOut.length ) :
						matcherOut
				);
				if ( postFinder ) {
					postFinder( null, results, matcherOut, xml );
				} else {
					push.apply( results, matcherOut );
				}
			}
		});
	}
	
	function matcherFromTokens( tokens ) {
		var checkContext, matcher, j,
			len = tokens.length,
			leadingRelative = Expr.relative[ tokens[0].type ],
			implicitRelative = leadingRelative || Expr.relative[" "],
			i = leadingRelative ? 1 : 0,
	
			// The foundational matcher ensures that elements are reachable from top-level context(s)
			matchContext = addCombinator( function( elem ) {
				return elem === checkContext;
			}, implicitRelative, true ),
			matchAnyContext = addCombinator( function( elem ) {
				return indexOf( checkContext, elem ) > -1;
			}, implicitRelative, true ),
			matchers = [ function( elem, context, xml ) {
				var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
					(checkContext = context).nodeType ?
						matchContext( elem, context, xml ) :
						matchAnyContext( elem, context, xml ) );
				// Avoid hanging onto element (issue #299)
				checkContext = null;
				return ret;
			} ];
	
		for ( ; i < len; i++ ) {
			if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
				matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
			} else {
				matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
	
				// Return special upon seeing a positional matcher
				if ( matcher[ expando ] ) {
					// Find the next relative operator (if any) for proper handling
					j = ++i;
					for ( ; j < len; j++ ) {
						if ( Expr.relative[ tokens[j].type ] ) {
							break;
						}
					}
					return setMatcher(
						i > 1 && elementMatcher( matchers ),
						i > 1 && toSelector(
							// If the preceding token was a descendant combinator, insert an implicit any-element `*`
							tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
						).replace( rtrim, "$1" ),
						matcher,
						i < j && matcherFromTokens( tokens.slice( i, j ) ),
						j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
						j < len && toSelector( tokens )
					);
				}
				matchers.push( matcher );
			}
		}
	
		return elementMatcher( matchers );
	}
	
	function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
		var bySet = setMatchers.length > 0,
			byElement = elementMatchers.length > 0,
			superMatcher = function( seed, context, xml, results, outermost ) {
				var elem, j, matcher,
					matchedCount = 0,
					i = "0",
					unmatched = seed && [],
					setMatched = [],
					contextBackup = outermostContext,
					// We must always have either seed elements or outermost context
					elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
					// Use integer dirruns iff this is the outermost matcher
					dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
					len = elems.length;
	
				if ( outermost ) {
					outermostContext = context === document || context || outermost;
				}
	
				// Add elements passing elementMatchers directly to results
				// Support: IE<9, Safari
				// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
				for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
					if ( byElement && elem ) {
						j = 0;
						if ( !context && elem.ownerDocument !== document ) {
							setDocument( elem );
							xml = !documentIsHTML;
						}
						while ( (matcher = elementMatchers[j++]) ) {
							if ( matcher( elem, context || document, xml) ) {
								results.push( elem );
								break;
							}
						}
						if ( outermost ) {
							dirruns = dirrunsUnique;
						}
					}
	
					// Track unmatched elements for set filters
					if ( bySet ) {
						// They will have gone through all possible matchers
						if ( (elem = !matcher && elem) ) {
							matchedCount--;
						}
	
						// Lengthen the array for every element, matched or not
						if ( seed ) {
							unmatched.push( elem );
						}
					}
				}
	
				// `i` is now the count of elements visited above, and adding it to `matchedCount`
				// makes the latter nonnegative.
				matchedCount += i;
	
				// Apply set filters to unmatched elements
				// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
				// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
				// no element matchers and no seed.
				// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
				// case, which will result in a "00" `matchedCount` that differs from `i` but is also
				// numerically zero.
				if ( bySet && i !== matchedCount ) {
					j = 0;
					while ( (matcher = setMatchers[j++]) ) {
						matcher( unmatched, setMatched, context, xml );
					}
	
					if ( seed ) {
						// Reintegrate element matches to eliminate the need for sorting
						if ( matchedCount > 0 ) {
							while ( i-- ) {
								if ( !(unmatched[i] || setMatched[i]) ) {
									setMatched[i] = pop.call( results );
								}
							}
						}
	
						// Discard index placeholder values to get only actual matches
						setMatched = condense( setMatched );
					}
	
					// Add matches to results
					push.apply( results, setMatched );
	
					// Seedless set matches succeeding multiple successful matchers stipulate sorting
					if ( outermost && !seed && setMatched.length > 0 &&
						( matchedCount + setMatchers.length ) > 1 ) {
	
						Sizzle.uniqueSort( results );
					}
				}
	
				// Override manipulation of globals by nested matchers
				if ( outermost ) {
					dirruns = dirrunsUnique;
					outermostContext = contextBackup;
				}
	
				return unmatched;
			};
	
		return bySet ?
			markFunction( superMatcher ) :
			superMatcher;
	}
	
	compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
		var i,
			setMatchers = [],
			elementMatchers = [],
			cached = compilerCache[ selector + " " ];
	
		if ( !cached ) {
			// Generate a function of recursive functions that can be used to check each element
			if ( !match ) {
				match = tokenize( selector );
			}
			i = match.length;
			while ( i-- ) {
				cached = matcherFromTokens( match[i] );
				if ( cached[ expando ] ) {
					setMatchers.push( cached );
				} else {
					elementMatchers.push( cached );
				}
			}
	
			// Cache the compiled function
			cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
	
			// Save selector and tokenization
			cached.selector = selector;
		}
		return cached;
	};
	
	/**
	 * A low-level selection function that works with Sizzle's compiled
	 *  selector functions
	 * @param {String|Function} selector A selector or a pre-compiled
	 *  selector function built with Sizzle.compile
	 * @param {Element} context
	 * @param {Array} [results]
	 * @param {Array} [seed] A set of elements to match against
	 */
	select = Sizzle.select = function( selector, context, results, seed ) {
		var i, tokens, token, type, find,
			compiled = typeof selector === "function" && selector,
			match = !seed && tokenize( (selector = compiled.selector || selector) );
	
		results = results || [];
	
		// Try to minimize operations if there is only one selector in the list and no seed
		// (the latter of which guarantees us context)
		if ( match.length === 1 ) {
	
			// Reduce context if the leading compound selector is an ID
			tokens = match[0] = match[0].slice( 0 );
			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
					context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
	
				context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
				if ( !context ) {
					return results;
	
				// Precompiled matchers will still verify ancestry, so step up a level
				} else if ( compiled ) {
					context = context.parentNode;
				}
	
				selector = selector.slice( tokens.shift().value.length );
			}
	
			// Fetch a seed set for right-to-left matching
			i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
			while ( i-- ) {
				token = tokens[i];
	
				// Abort if we hit a combinator
				if ( Expr.relative[ (type = token.type) ] ) {
					break;
				}
				if ( (find = Expr.find[ type ]) ) {
					// Search, expanding context for leading sibling combinators
					if ( (seed = find(
						token.matches[0].replace( runescape, funescape ),
						rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
					)) ) {
	
						// If seed is empty or no tokens remain, we can return early
						tokens.splice( i, 1 );
						selector = seed.length && toSelector( tokens );
						if ( !selector ) {
							push.apply( results, seed );
							return results;
						}
	
						break;
					}
				}
			}
		}
	
		// Compile and execute a filtering function if one is not provided
		// Provide `match` to avoid retokenization if we modified the selector above
		( compiled || compile( selector, match ) )(
			seed,
			context,
			!documentIsHTML,
			results,
			!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
		);
		return results;
	};
	
	// One-time assignments
	
	// Sort stability
	support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
	
	// Support: Chrome 14-35+
	// Always assume duplicates if they aren't passed to the comparison function
	support.detectDuplicates = !!hasDuplicate;
	
	// Initialize against the default document
	setDocument();
	
	// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
	// Detached nodes confoundingly follow *each other*
	support.sortDetached = assert(function( el ) {
		// Should return 1, but returns 4 (following)
		return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
	});
	
	// Support: IE<8
	// Prevent attribute/property "interpolation"
	// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
	if ( !assert(function( el ) {
		el.innerHTML = "<a href='#'></a>";
		return el.firstChild.getAttribute("href") === "#" ;
	}) ) {
		addHandle( "type|href|height|width", function( elem, name, isXML ) {
			if ( !isXML ) {
				return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
			}
		});
	}
	
	// Support: IE<9
	// Use defaultValue in place of getAttribute("value")
	if ( !support.attributes || !assert(function( el ) {
		el.innerHTML = "<input/>";
		el.firstChild.setAttribute( "value", "" );
		return el.firstChild.getAttribute( "value" ) === "";
	}) ) {
		addHandle( "value", function( elem, name, isXML ) {
			if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
				return elem.defaultValue;
			}
		});
	}
	
	// Support: IE<9
	// Use getAttributeNode to fetch booleans when getAttribute lies
	if ( !assert(function( el ) {
		return el.getAttribute("disabled") == null;
	}) ) {
		addHandle( booleans, function( elem, name, isXML ) {
			var val;
			if ( !isXML ) {
				return elem[ name ] === true ? name.toLowerCase() :
						(val = elem.getAttributeNode( name )) && val.specified ?
						val.value :
					null;
			}
		});
	}
	
	return Sizzle;
	
	})( window );
	
	
	
	jQuery.find = Sizzle;
	jQuery.expr = Sizzle.selectors;
	
	// Deprecated
	jQuery.expr[ ":" ] = jQuery.expr.pseudos;
	jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
	jQuery.text = Sizzle.getText;
	jQuery.isXMLDoc = Sizzle.isXML;
	jQuery.contains = Sizzle.contains;
	jQuery.escapeSelector = Sizzle.escape;
	
	
	
	
	var dir = function( elem, dir, until ) {
		var matched = [],
			truncate = until !== undefined;
	
		while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
			if ( elem.nodeType === 1 ) {
				if ( truncate && jQuery( elem ).is( until ) ) {
					break;
				}
				matched.push( elem );
			}
		}
		return matched;
	};
	
	
	var siblings = function( n, elem ) {
		var matched = [];
	
		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				matched.push( n );
			}
		}
	
		return matched;
	};
	
	
	var rneedsContext = jQuery.expr.match.needsContext;
	
	
	
	function nodeName( elem, name ) {
	
	  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
	
	};
	var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
	
	
	
	var risSimple = /^.[^:#\[\.,]*$/;
	
	// Implement the identical functionality for filter and not
	function winnow( elements, qualifier, not ) {
		if ( jQuery.isFunction( qualifier ) ) {
			return jQuery.grep( elements, function( elem, i ) {
				return !!qualifier.call( elem, i, elem ) !== not;
			} );
		}
	
		// Single element
		if ( qualifier.nodeType ) {
			return jQuery.grep( elements, function( elem ) {
				return ( elem === qualifier ) !== not;
			} );
		}
	
		// Arraylike of elements (jQuery, arguments, Array)
		if ( typeof qualifier !== "string" ) {
			return jQuery.grep( elements, function( elem ) {
				return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
			} );
		}
	
		// Simple selector that can be filtered directly, removing non-Elements
		if ( risSimple.test( qualifier ) ) {
			return jQuery.filter( qualifier, elements, not );
		}
	
		// Complex selector, compare the two sets, removing non-Elements
		qualifier = jQuery.filter( qualifier, elements );
		return jQuery.grep( elements, function( elem ) {
			return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
		} );
	}
	
	jQuery.filter = function( expr, elems, not ) {
		var elem = elems[ 0 ];
	
		if ( not ) {
			expr = ":not(" + expr + ")";
		}
	
		if ( elems.length === 1 && elem.nodeType === 1 ) {
			return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
		}
	
		return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
			return elem.nodeType === 1;
		} ) );
	};
	
	jQuery.fn.extend( {
		find: function( selector ) {
			var i, ret,
				len = this.length,
				self = this;
	
			if ( typeof selector !== "string" ) {
				return this.pushStack( jQuery( selector ).filter( function() {
					for ( i = 0; i < len; i++ ) {
						if ( jQuery.contains( self[ i ], this ) ) {
							return true;
						}
					}
				} ) );
			}
	
			ret = this.pushStack( [] );
	
			for ( i = 0; i < len; i++ ) {
				jQuery.find( selector, self[ i ], ret );
			}
	
			return len > 1 ? jQuery.uniqueSort( ret ) : ret;
		},
		filter: function( selector ) {
			return this.pushStack( winnow( this, selector || [], false ) );
		},
		not: function( selector ) {
			return this.pushStack( winnow( this, selector || [], true ) );
		},
		is: function( selector ) {
			return !!winnow(
				this,
	
				// If this is a positional/relative selector, check membership in the returned set
				// so $("p:first").is("p:last") won't return true for a doc with two "p".
				typeof selector === "string" && rneedsContext.test( selector ) ?
					jQuery( selector ) :
					selector || [],
				false
			).length;
		}
	} );
	
	
	// Initialize a jQuery object
	
	
	// A central reference to the root jQuery(document)
	var rootjQuery,
	
		// A simple way to check for HTML strings
		// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
		// Strict HTML recognition (#11290: must start with <)
		// Shortcut simple #id case for speed
		rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
	
		init = jQuery.fn.init = function( selector, context, root ) {
			var match, elem;
	
			// HANDLE: $(""), $(null), $(undefined), $(false)
			if ( !selector ) {
				return this;
			}
	
			// Method init() accepts an alternate rootjQuery
			// so migrate can support jQuery.sub (gh-2101)
			root = root || rootjQuery;
	
			// Handle HTML strings
			if ( typeof selector === "string" ) {
				if ( selector[ 0 ] === "<" &&
					selector[ selector.length - 1 ] === ">" &&
					selector.length >= 3 ) {
	
					// Assume that strings that start and end with <> are HTML and skip the regex check
					match = [ null, selector, null ];
	
				} else {
					match = rquickExpr.exec( selector );
				}
	
				// Match html or make sure no context is specified for #id
				if ( match && ( match[ 1 ] || !context ) ) {
	
					// HANDLE: $(html) -> $(array)
					if ( match[ 1 ] ) {
						context = context instanceof jQuery ? context[ 0 ] : context;
	
						// Option to run scripts is true for back-compat
						// Intentionally let the error be thrown if parseHTML is not present
						jQuery.merge( this, jQuery.parseHTML(
							match[ 1 ],
							context && context.nodeType ? context.ownerDocument || context : document,
							true
						) );
	
						// HANDLE: $(html, props)
						if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
							for ( match in context ) {
	
								// Properties of context are called as methods if possible
								if ( jQuery.isFunction( this[ match ] ) ) {
									this[ match ]( context[ match ] );
	
								// ...and otherwise set as attributes
								} else {
									this.attr( match, context[ match ] );
								}
							}
						}
	
						return this;
	
					// HANDLE: $(#id)
					} else {
						elem = document.getElementById( match[ 2 ] );
	
						if ( elem ) {
	
							// Inject the element directly into the jQuery object
							this[ 0 ] = elem;
							this.length = 1;
						}
						return this;
					}
	
				// HANDLE: $(expr, $(...))
				} else if ( !context || context.jquery ) {
					return ( context || root ).find( selector );
	
				// HANDLE: $(expr, context)
				// (which is just equivalent to: $(context).find(expr)
				} else {
					return this.constructor( context ).find( selector );
				}
	
			// HANDLE: $(DOMElement)
			} else if ( selector.nodeType ) {
				this[ 0 ] = selector;
				this.length = 1;
				return this;
	
			// HANDLE: $(function)
			// Shortcut for document ready
			} else if ( jQuery.isFunction( selector ) ) {
				return root.ready !== undefined ?
					root.ready( selector ) :
	
					// Execute immediately if ready is not present
					selector( jQuery );
			}
	
			return jQuery.makeArray( selector, this );
		};
	
	// Give the init function the jQuery prototype for later instantiation
	init.prototype = jQuery.fn;
	
	// Initialize central reference
	rootjQuery = jQuery( document );
	
	
	var rparentsprev = /^(?:parents|prev(?:Until|All))/,
	
		// Methods guaranteed to produce a unique set when starting from a unique set
		guaranteedUnique = {
			children: true,
			contents: true,
			next: true,
			prev: true
		};
	
	jQuery.fn.extend( {
		has: function( target ) {
			var targets = jQuery( target, this ),
				l = targets.length;
	
			return this.filter( function() {
				var i = 0;
				for ( ; i < l; i++ ) {
					if ( jQuery.contains( this, targets[ i ] ) ) {
						return true;
					}
				}
			} );
		},
	
		closest: function( selectors, context ) {
			var cur,
				i = 0,
				l = this.length,
				matched = [],
				targets = typeof selectors !== "string" && jQuery( selectors );
	
			// Positional selectors never match, since there's no _selection_ context
			if ( !rneedsContext.test( selectors ) ) {
				for ( ; i < l; i++ ) {
					for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
	
						// Always skip document fragments
						if ( cur.nodeType < 11 && ( targets ?
							targets.index( cur ) > -1 :
	
							// Don't pass non-elements to Sizzle
							cur.nodeType === 1 &&
								jQuery.find.matchesSelector( cur, selectors ) ) ) {
	
							matched.push( cur );
							break;
						}
					}
				}
			}
	
			return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
		},
	
		// Determine the position of an element within the set
		index: function( elem ) {
	
			// No argument, return index in parent
			if ( !elem ) {
				return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
			}
	
			// Index in selector
			if ( typeof elem === "string" ) {
				return indexOf.call( jQuery( elem ), this[ 0 ] );
			}
	
			// Locate the position of the desired element
			return indexOf.call( this,
	
				// If it receives a jQuery object, the first element is used
				elem.jquery ? elem[ 0 ] : elem
			);
		},
	
		add: function( selector, context ) {
			return this.pushStack(
				jQuery.uniqueSort(
					jQuery.merge( this.get(), jQuery( selector, context ) )
				)
			);
		},
	
		addBack: function( selector ) {
			return this.add( selector == null ?
				this.prevObject : this.prevObject.filter( selector )
			);
		}
	} );
	
	function sibling( cur, dir ) {
		while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
		return cur;
	}
	
	jQuery.each( {
		parent: function( elem ) {
			var parent = elem.parentNode;
			return parent && parent.nodeType !== 11 ? parent : null;
		},
		parents: function( elem ) {
			return dir( elem, "parentNode" );
		},
		parentsUntil: function( elem, i, until ) {
			return dir( elem, "parentNode", until );
		},
		next: function( elem ) {
			return sibling( elem, "nextSibling" );
		},
		prev: function( elem ) {
			return sibling( elem, "previousSibling" );
		},
		nextAll: function( elem ) {
			return dir( elem, "nextSibling" );
		},
		prevAll: function( elem ) {
			return dir( elem, "previousSibling" );
		},
		nextUntil: function( elem, i, until ) {
			return dir( elem, "nextSibling", until );
		},
		prevUntil: function( elem, i, until ) {
			return dir( elem, "previousSibling", until );
		},
		siblings: function( elem ) {
			return siblings( ( elem.parentNode || {} ).firstChild, elem );
		},
		children: function( elem ) {
			return siblings( elem.firstChild );
		},
		contents: function( elem ) {
	        if ( nodeName( elem, "iframe" ) ) {
	            return elem.contentDocument;
	        }
	
	        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
	        // Treat the template element as a regular one in browsers that
	        // don't support it.
	        if ( nodeName( elem, "template" ) ) {
	            elem = elem.content || elem;
	        }
	
	        return jQuery.merge( [], elem.childNodes );
		}
	}, function( name, fn ) {
		jQuery.fn[ name ] = function( until, selector ) {
			var matched = jQuery.map( this, fn, until );
	
			if ( name.slice( -5 ) !== "Until" ) {
				selector = until;
			}
	
			if ( selector && typeof selector === "string" ) {
				matched = jQuery.filter( selector, matched );
			}
	
			if ( this.length > 1 ) {
	
				// Remove duplicates
				if ( !guaranteedUnique[ name ] ) {
					jQuery.uniqueSort( matched );
				}
	
				// Reverse order for parents* and prev-derivatives
				if ( rparentsprev.test( name ) ) {
					matched.reverse();
				}
			}
	
			return this.pushStack( matched );
		};
	} );
	var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
	
	
	
	// Convert String-formatted options into Object-formatted ones
	function createOptions( options ) {
		var object = {};
		jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
			object[ flag ] = true;
		} );
		return object;
	}
	
	/*
	 * Create a callback list using the following parameters:
	 *
	 *	options: an optional list of space-separated options that will change how
	 *			the callback list behaves or a more traditional option object
	 *
	 * By default a callback list will act like an event callback list and can be
	 * "fired" multiple times.
	 *
	 * Possible options:
	 *
	 *	once:			will ensure the callback list can only be fired once (like a Deferred)
	 *
	 *	memory:			will keep track of previous values and will call any callback added
	 *					after the list has been fired right away with the latest "memorized"
	 *					values (like a Deferred)
	 *
	 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
	 *
	 *	stopOnFalse:	interrupt callings when a callback returns false
	 *
	 */
	jQuery.Callbacks = function( options ) {
	
		// Convert options from String-formatted to Object-formatted if needed
		// (we check in cache first)
		options = typeof options === "string" ?
			createOptions( options ) :
			jQuery.extend( {}, options );
	
		var // Flag to know if list is currently firing
			firing,
	
			// Last fire value for non-forgettable lists
			memory,
	
			// Flag to know if list was already fired
			fired,
	
			// Flag to prevent firing
			locked,
	
			// Actual callback list
			list = [],
	
			// Queue of execution data for repeatable lists
			queue = [],
	
			// Index of currently firing callback (modified by add/remove as needed)
			firingIndex = -1,
	
			// Fire callbacks
			fire = function() {
	
				// Enforce single-firing
				locked = locked || options.once;
	
				// Execute callbacks for all pending executions,
				// respecting firingIndex overrides and runtime changes
				fired = firing = true;
				for ( ; queue.length; firingIndex = -1 ) {
					memory = queue.shift();
					while ( ++firingIndex < list.length ) {
	
						// Run callback and check for early termination
						if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
							options.stopOnFalse ) {
	
							// Jump to end and forget the data so .add doesn't re-fire
							firingIndex = list.length;
							memory = false;
						}
					}
				}
	
				// Forget the data if we're done with it
				if ( !options.memory ) {
					memory = false;
				}
	
				firing = false;
	
				// Clean up if we're done firing for good
				if ( locked ) {
	
					// Keep an empty list if we have data for future add calls
					if ( memory ) {
						list = [];
	
					// Otherwise, this object is spent
					} else {
						list = "";
					}
				}
			},
	
			// Actual Callbacks object
			self = {
	
				// Add a callback or a collection of callbacks to the list
				add: function() {
					if ( list ) {
	
						// If we have memory from a past run, we should fire after adding
						if ( memory && !firing ) {
							firingIndex = list.length - 1;
							queue.push( memory );
						}
	
						( function add( args ) {
							jQuery.each( args, function( _, arg ) {
								if ( jQuery.isFunction( arg ) ) {
									if ( !options.unique || !self.has( arg ) ) {
										list.push( arg );
									}
								} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
	
									// Inspect recursively
									add( arg );
								}
							} );
						} )( arguments );
	
						if ( memory && !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Remove a callback from the list
				remove: function() {
					jQuery.each( arguments, function( _, arg ) {
						var index;
						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
							list.splice( index, 1 );
	
							// Handle firing indexes
							if ( index <= firingIndex ) {
								firingIndex--;
							}
						}
					} );
					return this;
				},
	
				// Check if a given callback is in the list.
				// If no argument is given, return whether or not list has callbacks attached.
				has: function( fn ) {
					return fn ?
						jQuery.inArray( fn, list ) > -1 :
						list.length > 0;
				},
	
				// Remove all callbacks from the list
				empty: function() {
					if ( list ) {
						list = [];
					}
					return this;
				},
	
				// Disable .fire and .add
				// Abort any current/pending executions
				// Clear all callbacks and values
				disable: function() {
					locked = queue = [];
					list = memory = "";
					return this;
				},
				disabled: function() {
					return !list;
				},
	
				// Disable .fire
				// Also disable .add unless we have memory (since it would have no effect)
				// Abort any pending executions
				lock: function() {
					locked = queue = [];
					if ( !memory && !firing ) {
						list = memory = "";
					}
					return this;
				},
				locked: function() {
					return !!locked;
				},
	
				// Call all callbacks with the given context and arguments
				fireWith: function( context, args ) {
					if ( !locked ) {
						args = args || [];
						args = [ context, args.slice ? args.slice() : args ];
						queue.push( args );
						if ( !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Call all the callbacks with the given arguments
				fire: function() {
					self.fireWith( this, arguments );
					return this;
				},
	
				// To know if the callbacks have already been called at least once
				fired: function() {
					return !!fired;
				}
			};
	
		return self;
	};
	
	
	function Identity( v ) {
		return v;
	}
	function Thrower( ex ) {
		throw ex;
	}
	
	function adoptValue( value, resolve, reject, noValue ) {
		var method;
	
		try {
	
			// Check for promise aspect first to privilege synchronous behavior
			if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
				method.call( value ).done( resolve ).fail( reject );
	
			// Other thenables
			} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
				method.call( value, resolve, reject );
	
			// Other non-thenables
			} else {
	
				// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
				// * false: [ value ].slice( 0 ) => resolve( value )
				// * true: [ value ].slice( 1 ) => resolve()
				resolve.apply( undefined, [ value ].slice( noValue ) );
			}
	
		// For Promises/A+, convert exceptions into rejections
		// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
		// Deferred#then to conditionally suppress rejection.
		} catch ( value ) {
	
			// Support: Android 4.0 only
			// Strict mode functions invoked without .call/.apply get global-object context
			reject.apply( undefined, [ value ] );
		}
	}
	
	jQuery.extend( {
	
		Deferred: function( func ) {
			var tuples = [
	
					// action, add listener, callbacks,
					// ... .then handlers, argument index, [final state]
					[ "notify", "progress", jQuery.Callbacks( "memory" ),
						jQuery.Callbacks( "memory" ), 2 ],
					[ "resolve", "done", jQuery.Callbacks( "once memory" ),
						jQuery.Callbacks( "once memory" ), 0, "resolved" ],
					[ "reject", "fail", jQuery.Callbacks( "once memory" ),
						jQuery.Callbacks( "once memory" ), 1, "rejected" ]
				],
				state = "pending",
				promise = {
					state: function() {
						return state;
					},
					always: function() {
						deferred.done( arguments ).fail( arguments );
						return this;
					},
					"catch": function( fn ) {
						return promise.then( null, fn );
					},
	
					// Keep pipe for back-compat
					pipe: function( /* fnDone, fnFail, fnProgress */ ) {
						var fns = arguments;
	
						return jQuery.Deferred( function( newDefer ) {
							jQuery.each( tuples, function( i, tuple ) {
	
								// Map tuples (progress, done, fail) to arguments (done, fail, progress)
								var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
	
								// deferred.progress(function() { bind to newDefer or newDefer.notify })
								// deferred.done(function() { bind to newDefer or newDefer.resolve })
								// deferred.fail(function() { bind to newDefer or newDefer.reject })
								deferred[ tuple[ 1 ] ]( function() {
									var returned = fn && fn.apply( this, arguments );
									if ( returned && jQuery.isFunction( returned.promise ) ) {
										returned.promise()
											.progress( newDefer.notify )
											.done( newDefer.resolve )
											.fail( newDefer.reject );
									} else {
										newDefer[ tuple[ 0 ] + "With" ](
											this,
											fn ? [ returned ] : arguments
										);
									}
								} );
							} );
							fns = null;
						} ).promise();
					},
					then: function( onFulfilled, onRejected, onProgress ) {
						var maxDepth = 0;
						function resolve( depth, deferred, handler, special ) {
							return function() {
								var that = this,
									args = arguments,
									mightThrow = function() {
										var returned, then;
	
										// Support: Promises/A+ section 2.3.3.3.3
										// https://promisesaplus.com/#point-59
										// Ignore double-resolution attempts
										if ( depth < maxDepth ) {
											return;
										}
	
										returned = handler.apply( that, args );
	
										// Support: Promises/A+ section 2.3.1
										// https://promisesaplus.com/#point-48
										if ( returned === deferred.promise() ) {
											throw new TypeError( "Thenable self-resolution" );
										}
	
										// Support: Promises/A+ sections 2.3.3.1, 3.5
										// https://promisesaplus.com/#point-54
										// https://promisesaplus.com/#point-75
										// Retrieve `then` only once
										then = returned &&
	
											// Support: Promises/A+ section 2.3.4
											// https://promisesaplus.com/#point-64
											// Only check objects and functions for thenability
											( typeof returned === "object" ||
												typeof returned === "function" ) &&
											returned.then;
	
										// Handle a returned thenable
										if ( jQuery.isFunction( then ) ) {
	
											// Special processors (notify) just wait for resolution
											if ( special ) {
												then.call(
													returned,
													resolve( maxDepth, deferred, Identity, special ),
													resolve( maxDepth, deferred, Thrower, special )
												);
	
											// Normal processors (resolve) also hook into progress
											} else {
	
												// ...and disregard older resolution values
												maxDepth++;
	
												then.call(
													returned,
													resolve( maxDepth, deferred, Identity, special ),
													resolve( maxDepth, deferred, Thrower, special ),
													resolve( maxDepth, deferred, Identity,
														deferred.notifyWith )
												);
											}
	
										// Handle all other returned values
										} else {
	
											// Only substitute handlers pass on context
											// and multiple values (non-spec behavior)
											if ( handler !== Identity ) {
												that = undefined;
												args = [ returned ];
											}
	
											// Process the value(s)
											// Default process is resolve
											( special || deferred.resolveWith )( that, args );
										}
									},
	
									// Only normal processors (resolve) catch and reject exceptions
									process = special ?
										mightThrow :
										function() {
											try {
												mightThrow();
											} catch ( e ) {
	
												if ( jQuery.Deferred.exceptionHook ) {
													jQuery.Deferred.exceptionHook( e,
														process.stackTrace );
												}
	
												// Support: Promises/A+ section 2.3.3.3.4.1
												// https://promisesaplus.com/#point-61
												// Ignore post-resolution exceptions
												if ( depth + 1 >= maxDepth ) {
	
													// Only substitute handlers pass on context
													// and multiple values (non-spec behavior)
													if ( handler !== Thrower ) {
														that = undefined;
														args = [ e ];
													}
	
													deferred.rejectWith( that, args );
												}
											}
										};
	
								// Support: Promises/A+ section 2.3.3.3.1
								// https://promisesaplus.com/#point-57
								// Re-resolve promises immediately to dodge false rejection from
								// subsequent errors
								if ( depth ) {
									process();
								} else {
	
									// Call an optional hook to record the stack, in case of exception
									// since it's otherwise lost when execution goes async
									if ( jQuery.Deferred.getStackHook ) {
										process.stackTrace = jQuery.Deferred.getStackHook();
									}
									window.setTimeout( process );
								}
							};
						}
	
						return jQuery.Deferred( function( newDefer ) {
	
							// progress_handlers.add( ... )
							tuples[ 0 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onProgress ) ?
										onProgress :
										Identity,
									newDefer.notifyWith
								)
							);
	
							// fulfilled_handlers.add( ... )
							tuples[ 1 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onFulfilled ) ?
										onFulfilled :
										Identity
								)
							);
	
							// rejected_handlers.add( ... )
							tuples[ 2 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onRejected ) ?
										onRejected :
										Thrower
								)
							);
						} ).promise();
					},
	
					// Get a promise for this deferred
					// If obj is provided, the promise aspect is added to the object
					promise: function( obj ) {
						return obj != null ? jQuery.extend( obj, promise ) : promise;
					}
				},
				deferred = {};
	
			// Add list-specific methods
			jQuery.each( tuples, function( i, tuple ) {
				var list = tuple[ 2 ],
					stateString = tuple[ 5 ];
	
				// promise.progress = list.add
				// promise.done = list.add
				// promise.fail = list.add
				promise[ tuple[ 1 ] ] = list.add;
	
				// Handle state
				if ( stateString ) {
					list.add(
						function() {
	
							// state = "resolved" (i.e., fulfilled)
							// state = "rejected"
							state = stateString;
						},
	
						// rejected_callbacks.disable
						// fulfilled_callbacks.disable
						tuples[ 3 - i ][ 2 ].disable,
	
						// progress_callbacks.lock
						tuples[ 0 ][ 2 ].lock
					);
				}
	
				// progress_handlers.fire
				// fulfilled_handlers.fire
				// rejected_handlers.fire
				list.add( tuple[ 3 ].fire );
	
				// deferred.notify = function() { deferred.notifyWith(...) }
				// deferred.resolve = function() { deferred.resolveWith(...) }
				// deferred.reject = function() { deferred.rejectWith(...) }
				deferred[ tuple[ 0 ] ] = function() {
					deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
					return this;
				};
	
				// deferred.notifyWith = list.fireWith
				// deferred.resolveWith = list.fireWith
				// deferred.rejectWith = list.fireWith
				deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
			} );
	
			// Make the deferred a promise
			promise.promise( deferred );
	
			// Call given func if any
			if ( func ) {
				func.call( deferred, deferred );
			}
	
			// All done!
			return deferred;
		},
	
		// Deferred helper
		when: function( singleValue ) {
			var
	
				// count of uncompleted subordinates
				remaining = arguments.length,
	
				// count of unprocessed arguments
				i = remaining,
	
				// subordinate fulfillment data
				resolveContexts = Array( i ),
				resolveValues = slice.call( arguments ),
	
				// the master Deferred
				master = jQuery.Deferred(),
	
				// subordinate callback factory
				updateFunc = function( i ) {
					return function( value ) {
						resolveContexts[ i ] = this;
						resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
						if ( !( --remaining ) ) {
							master.resolveWith( resolveContexts, resolveValues );
						}
					};
				};
	
			// Single- and empty arguments are adopted like Promise.resolve
			if ( remaining <= 1 ) {
				adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
					!remaining );
	
				// Use .then() to unwrap secondary thenables (cf. gh-3000)
				if ( master.state() === "pending" ||
					jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
	
					return master.then();
				}
			}
	
			// Multiple arguments are aggregated like Promise.all array elements
			while ( i-- ) {
				adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
			}
	
			return master.promise();
		}
	} );
	
	
	// These usually indicate a programmer mistake during development,
	// warn about them ASAP rather than swallowing them by default.
	var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
	
	jQuery.Deferred.exceptionHook = function( error, stack ) {
	
		// Support: IE 8 - 9 only
		// Console exists when dev tools are open, which can happen at any time
		if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
			window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
		}
	};
	
	
	
	
	jQuery.readyException = function( error ) {
		window.setTimeout( function() {
			throw error;
		} );
	};
	
	
	
	
	// The deferred used on DOM ready
	var readyList = jQuery.Deferred();
	
	jQuery.fn.ready = function( fn ) {
	
		readyList
			.then( fn )
	
			// Wrap jQuery.readyException in a function so that the lookup
			// happens at the time of error handling instead of callback
			// registration.
			.catch( function( error ) {
				jQuery.readyException( error );
			} );
	
		return this;
	};
	
	jQuery.extend( {
	
		// Is the DOM ready to be used? Set to true once it occurs.
		isReady: false,
	
		// A counter to track how many items to wait for before
		// the ready event fires. See #6781
		readyWait: 1,
	
		// Handle when the DOM is ready
		ready: function( wait ) {
	
			// Abort if there are pending holds or we're already ready
			if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
				return;
			}
	
			// Remember that the DOM is ready
			jQuery.isReady = true;
	
			// If a normal DOM Ready event fired, decrement, and wait if need be
			if ( wait !== true && --jQuery.readyWait > 0 ) {
				return;
			}
	
			// If there are functions bound, to execute
			readyList.resolveWith( document, [ jQuery ] );
		}
	} );
	
	jQuery.ready.then = readyList.then;
	
	// The ready event handler and self cleanup method
	function completed() {
		document.removeEventListener( "DOMContentLoaded", completed );
		window.removeEventListener( "load", completed );
		jQuery.ready();
	}
	
	// Catch cases where $(document).ready() is called
	// after the browser event has already occurred.
	// Support: IE <=9 - 10 only
	// Older IE sometimes signals "interactive" too soon
	if ( document.readyState === "complete" ||
		( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
	
		// Handle it asynchronously to allow scripts the opportunity to delay ready
		window.setTimeout( jQuery.ready );
	
	} else {
	
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", completed );
	
		// A fallback to window.onload, that will always work
		window.addEventListener( "load", completed );
	}
	
	
	
	
	// Multifunctional method to get and set values of a collection
	// The value/s can optionally be executed if it's a function
	var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
		var i = 0,
			len = elems.length,
			bulk = key == null;
	
		// Sets many values
		if ( jQuery.type( key ) === "object" ) {
			chainable = true;
			for ( i in key ) {
				access( elems, fn, i, key[ i ], true, emptyGet, raw );
			}
	
		// Sets one value
		} else if ( value !== undefined ) {
			chainable = true;
	
			if ( !jQuery.isFunction( value ) ) {
				raw = true;
			}
	
			if ( bulk ) {
	
				// Bulk operations run against the entire set
				if ( raw ) {
					fn.call( elems, value );
					fn = null;
	
				// ...except when executing function values
				} else {
					bulk = fn;
					fn = function( elem, key, value ) {
						return bulk.call( jQuery( elem ), value );
					};
				}
			}
	
			if ( fn ) {
				for ( ; i < len; i++ ) {
					fn(
						elems[ i ], key, raw ?
						value :
						value.call( elems[ i ], i, fn( elems[ i ], key ) )
					);
				}
			}
		}
	
		if ( chainable ) {
			return elems;
		}
	
		// Gets
		if ( bulk ) {
			return fn.call( elems );
		}
	
		return len ? fn( elems[ 0 ], key ) : emptyGet;
	};
	var acceptData = function( owner ) {
	
		// Accepts only:
		//  - Node
		//    - Node.ELEMENT_NODE
		//    - Node.DOCUMENT_NODE
		//  - Object
		//    - Any
		return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
	};
	
	
	
	
	function Data() {
		this.expando = jQuery.expando + Data.uid++;
	}
	
	Data.uid = 1;
	
	Data.prototype = {
	
		cache: function( owner ) {
	
			// Check if the owner object already has a cache
			var value = owner[ this.expando ];
	
			// If not, create one
			if ( !value ) {
				value = {};
	
				// We can accept data for non-element nodes in modern browsers,
				// but we should not, see #8335.
				// Always return an empty object.
				if ( acceptData( owner ) ) {
	
					// If it is a node unlikely to be stringify-ed or looped over
					// use plain assignment
					if ( owner.nodeType ) {
						owner[ this.expando ] = value;
	
					// Otherwise secure it in a non-enumerable property
					// configurable must be true to allow the property to be
					// deleted when data is removed
					} else {
						Object.defineProperty( owner, this.expando, {
							value: value,
							configurable: true
						} );
					}
				}
			}
	
			return value;
		},
		set: function( owner, data, value ) {
			var prop,
				cache = this.cache( owner );
	
			// Handle: [ owner, key, value ] args
			// Always use camelCase key (gh-2257)
			if ( typeof data === "string" ) {
				cache[ jQuery.camelCase( data ) ] = value;
	
			// Handle: [ owner, { properties } ] args
			} else {
	
				// Copy the properties one-by-one to the cache object
				for ( prop in data ) {
					cache[ jQuery.camelCase( prop ) ] = data[ prop ];
				}
			}
			return cache;
		},
		get: function( owner, key ) {
			return key === undefined ?
				this.cache( owner ) :
	
				// Always use camelCase key (gh-2257)
				owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
		},
		access: function( owner, key, value ) {
	
			// In cases where either:
			//
			//   1. No key was specified
			//   2. A string key was specified, but no value provided
			//
			// Take the "read" path and allow the get method to determine
			// which value to return, respectively either:
			//
			//   1. The entire cache object
			//   2. The data stored at the key
			//
			if ( key === undefined ||
					( ( key && typeof key === "string" ) && value === undefined ) ) {
	
				return this.get( owner, key );
			}
	
			// When the key is not a string, or both a key and value
			// are specified, set or extend (existing objects) with either:
			//
			//   1. An object of properties
			//   2. A key and value
			//
			this.set( owner, key, value );
	
			// Since the "set" path can have two possible entry points
			// return the expected data based on which path was taken[*]
			return value !== undefined ? value : key;
		},
		remove: function( owner, key ) {
			var i,
				cache = owner[ this.expando ];
	
			if ( cache === undefined ) {
				return;
			}
	
			if ( key !== undefined ) {
	
				// Support array or space separated string of keys
				if ( Array.isArray( key ) ) {
	
					// If key is an array of keys...
					// We always set camelCase keys, so remove that.
					key = key.map( jQuery.camelCase );
				} else {
					key = jQuery.camelCase( key );
	
					// If a key with the spaces exists, use it.
					// Otherwise, create an array by matching non-whitespace
					key = key in cache ?
						[ key ] :
						( key.match( rnothtmlwhite ) || [] );
				}
	
				i = key.length;
	
				while ( i-- ) {
					delete cache[ key[ i ] ];
				}
			}
	
			// Remove the expando if there's no more data
			if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
	
				// Support: Chrome <=35 - 45
				// Webkit & Blink performance suffers when deleting properties
				// from DOM nodes, so set to undefined instead
				// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
				if ( owner.nodeType ) {
					owner[ this.expando ] = undefined;
				} else {
					delete owner[ this.expando ];
				}
			}
		},
		hasData: function( owner ) {
			var cache = owner[ this.expando ];
			return cache !== undefined && !jQuery.isEmptyObject( cache );
		}
	};
	var dataPriv = new Data();
	
	var dataUser = new Data();
	
	
	
	//	Implementation Summary
	//
	//	1. Enforce API surface and semantic compatibility with 1.9.x branch
	//	2. Improve the module's maintainability by reducing the storage
	//		paths to a single mechanism.
	//	3. Use the same single mechanism to support "private" and "user" data.
	//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
	//	5. Avoid exposing implementation details on user objects (eg. expando properties)
	//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
	
	var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
		rmultiDash = /[A-Z]/g;
	
	function getData( data ) {
		if ( data === "true" ) {
			return true;
		}
	
		if ( data === "false" ) {
			return false;
		}
	
		if ( data === "null" ) {
			return null;
		}
	
		// Only convert to a number if it doesn't change the string
		if ( data === +data + "" ) {
			return +data;
		}
	
		if ( rbrace.test( data ) ) {
			return JSON.parse( data );
		}
	
		return data;
	}
	
	function dataAttr( elem, key, data ) {
		var name;
	
		// If nothing was found internally, try to fetch any
		// data from the HTML5 data-* attribute
		if ( data === undefined && elem.nodeType === 1 ) {
			name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
			data = elem.getAttribute( name );
	
			if ( typeof data === "string" ) {
				try {
					data = getData( data );
				} catch ( e ) {}
	
				// Make sure we set the data so it isn't changed later
				dataUser.set( elem, key, data );
			} else {
				data = undefined;
			}
		}
		return data;
	}
	
	jQuery.extend( {
		hasData: function( elem ) {
			return dataUser.hasData( elem ) || dataPriv.hasData( elem );
		},
	
		data: function( elem, name, data ) {
			return dataUser.access( elem, name, data );
		},
	
		removeData: function( elem, name ) {
			dataUser.remove( elem, name );
		},
	
		// TODO: Now that all calls to _data and _removeData have been replaced
		// with direct calls to dataPriv methods, these can be deprecated.
		_data: function( elem, name, data ) {
			return dataPriv.access( elem, name, data );
		},
	
		_removeData: function( elem, name ) {
			dataPriv.remove( elem, name );
		}
	} );
	
	jQuery.fn.extend( {
		data: function( key, value ) {
			var i, name, data,
				elem = this[ 0 ],
				attrs = elem && elem.attributes;
	
			// Gets all values
			if ( key === undefined ) {
				if ( this.length ) {
					data = dataUser.get( elem );
	
					if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
						i = attrs.length;
						while ( i-- ) {
	
							// Support: IE 11 only
							// The attrs elements can be null (#14894)
							if ( attrs[ i ] ) {
								name = attrs[ i ].name;
								if ( name.indexOf( "data-" ) === 0 ) {
									name = jQuery.camelCase( name.slice( 5 ) );
									dataAttr( elem, name, data[ name ] );
								}
							}
						}
						dataPriv.set( elem, "hasDataAttrs", true );
					}
				}
	
				return data;
			}
	
			// Sets multiple values
			if ( typeof key === "object" ) {
				return this.each( function() {
					dataUser.set( this, key );
				} );
			}
	
			return access( this, function( value ) {
				var data;
	
				// The calling jQuery object (element matches) is not empty
				// (and therefore has an element appears at this[ 0 ]) and the
				// `value` parameter was not undefined. An empty jQuery object
				// will result in `undefined` for elem = this[ 0 ] which will
				// throw an exception if an attempt to read a data cache is made.
				if ( elem && value === undefined ) {
	
					// Attempt to get data from the cache
					// The key will always be camelCased in Data
					data = dataUser.get( elem, key );
					if ( data !== undefined ) {
						return data;
					}
	
					// Attempt to "discover" the data in
					// HTML5 custom data-* attrs
					data = dataAttr( elem, key );
					if ( data !== undefined ) {
						return data;
					}
	
					// We tried really hard, but the data doesn't exist.
					return;
				}
	
				// Set the data...
				this.each( function() {
	
					// We always store the camelCased key
					dataUser.set( this, key, value );
				} );
			}, null, value, arguments.length > 1, null, true );
		},
	
		removeData: function( key ) {
			return this.each( function() {
				dataUser.remove( this, key );
			} );
		}
	} );
	
	
	jQuery.extend( {
		queue: function( elem, type, data ) {
			var queue;
	
			if ( elem ) {
				type = ( type || "fx" ) + "queue";
				queue = dataPriv.get( elem, type );
	
				// Speed up dequeue by getting out quickly if this is just a lookup
				if ( data ) {
					if ( !queue || Array.isArray( data ) ) {
						queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
					} else {
						queue.push( data );
					}
				}
				return queue || [];
			}
		},
	
		dequeue: function( elem, type ) {
			type = type || "fx";
	
			var queue = jQuery.queue( elem, type ),
				startLength = queue.length,
				fn = queue.shift(),
				hooks = jQuery._queueHooks( elem, type ),
				next = function() {
					jQuery.dequeue( elem, type );
				};
	
			// If the fx queue is dequeued, always remove the progress sentinel
			if ( fn === "inprogress" ) {
				fn = queue.shift();
				startLength--;
			}
	
			if ( fn ) {
	
				// Add a progress sentinel to prevent the fx queue from being
				// automatically dequeued
				if ( type === "fx" ) {
					queue.unshift( "inprogress" );
				}
	
				// Clear up the last queue stop function
				delete hooks.stop;
				fn.call( elem, next, hooks );
			}
	
			if ( !startLength && hooks ) {
				hooks.empty.fire();
			}
		},
	
		// Not public - generate a queueHooks object, or return the current one
		_queueHooks: function( elem, type ) {
			var key = type + "queueHooks";
			return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
				empty: jQuery.Callbacks( "once memory" ).add( function() {
					dataPriv.remove( elem, [ type + "queue", key ] );
				} )
			} );
		}
	} );
	
	jQuery.fn.extend( {
		queue: function( type, data ) {
			var setter = 2;
	
			if ( typeof type !== "string" ) {
				data = type;
				type = "fx";
				setter--;
			}
	
			if ( arguments.length < setter ) {
				return jQuery.queue( this[ 0 ], type );
			}
	
			return data === undefined ?
				this :
				this.each( function() {
					var queue = jQuery.queue( this, type, data );
	
					// Ensure a hooks for this queue
					jQuery._queueHooks( this, type );
	
					if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
						jQuery.dequeue( this, type );
					}
				} );
		},
		dequeue: function( type ) {
			return this.each( function() {
				jQuery.dequeue( this, type );
			} );
		},
		clearQueue: function( type ) {
			return this.queue( type || "fx", [] );
		},
	
		// Get a promise resolved when queues of a certain type
		// are emptied (fx is the type by default)
		promise: function( type, obj ) {
			var tmp,
				count = 1,
				defer = jQuery.Deferred(),
				elements = this,
				i = this.length,
				resolve = function() {
					if ( !( --count ) ) {
						defer.resolveWith( elements, [ elements ] );
					}
				};
	
			if ( typeof type !== "string" ) {
				obj = type;
				type = undefined;
			}
			type = type || "fx";
	
			while ( i-- ) {
				tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
				if ( tmp && tmp.empty ) {
					count++;
					tmp.empty.add( resolve );
				}
			}
			resolve();
			return defer.promise( obj );
		}
	} );
	var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
	
	var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
	
	
	var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
	
	var isHiddenWithinTree = function( elem, el ) {
	
			// isHiddenWithinTree might be called from jQuery#filter function;
			// in that case, element will be second argument
			elem = el || elem;
	
			// Inline style trumps all
			return elem.style.display === "none" ||
				elem.style.display === "" &&
	
				// Otherwise, check computed style
				// Support: Firefox <=43 - 45
				// Disconnected elements can have computed display: none, so first confirm that elem is
				// in the document.
				jQuery.contains( elem.ownerDocument, elem ) &&
	
				jQuery.css( elem, "display" ) === "none";
		};
	
	var swap = function( elem, options, callback, args ) {
		var ret, name,
			old = {};
	
		// Remember the old values, and insert the new ones
		for ( name in options ) {
			old[ name ] = elem.style[ name ];
			elem.style[ name ] = options[ name ];
		}
	
		ret = callback.apply( elem, args || [] );
	
		// Revert the old values
		for ( name in options ) {
			elem.style[ name ] = old[ name ];
		}
	
		return ret;
	};
	
	
	
	
	function adjustCSS( elem, prop, valueParts, tween ) {
		var adjusted,
			scale = 1,
			maxIterations = 20,
			currentValue = tween ?
				function() {
					return tween.cur();
				} :
				function() {
					return jQuery.css( elem, prop, "" );
				},
			initial = currentValue(),
			unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
	
			// Starting value computation is required for potential unit mismatches
			initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
				rcssNum.exec( jQuery.css( elem, prop ) );
	
		if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
	
			// Trust units reported by jQuery.css
			unit = unit || initialInUnit[ 3 ];
	
			// Make sure we update the tween properties later on
			valueParts = valueParts || [];
	
			// Iteratively approximate from a nonzero starting point
			initialInUnit = +initial || 1;
	
			do {
	
				// If previous iteration zeroed out, double until we get *something*.
				// Use string for doubling so we don't accidentally see scale as unchanged below
				scale = scale || ".5";
	
				// Adjust and apply
				initialInUnit = initialInUnit / scale;
				jQuery.style( elem, prop, initialInUnit + unit );
	
			// Update scale, tolerating zero or NaN from tween.cur()
			// Break the loop if scale is unchanged or perfect, or if we've just had enough.
			} while (
				scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
			);
		}
	
		if ( valueParts ) {
			initialInUnit = +initialInUnit || +initial || 0;
	
			// Apply relative offset (+=/-=) if specified
			adjusted = valueParts[ 1 ] ?
				initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
				+valueParts[ 2 ];
			if ( tween ) {
				tween.unit = unit;
				tween.start = initialInUnit;
				tween.end = adjusted;
			}
		}
		return adjusted;
	}
	
	
	var defaultDisplayMap = {};
	
	function getDefaultDisplay( elem ) {
		var temp,
			doc = elem.ownerDocument,
			nodeName = elem.nodeName,
			display = defaultDisplayMap[ nodeName ];
	
		if ( display ) {
			return display;
		}
	
		temp = doc.body.appendChild( doc.createElement( nodeName ) );
		display = jQuery.css( temp, "display" );
	
		temp.parentNode.removeChild( temp );
	
		if ( display === "none" ) {
			display = "block";
		}
		defaultDisplayMap[ nodeName ] = display;
	
		return display;
	}
	
	function showHide( elements, show ) {
		var display, elem,
			values = [],
			index = 0,
			length = elements.length;
	
		// Determine new display value for elements that need to change
		for ( ; index < length; index++ ) {
			elem = elements[ index ];
			if ( !elem.style ) {
				continue;
			}
	
			display = elem.style.display;
			if ( show ) {
	
				// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
				// check is required in this first loop unless we have a nonempty display value (either
				// inline or about-to-be-restored)
				if ( display === "none" ) {
					values[ index ] = dataPriv.get( elem, "display" ) || null;
					if ( !values[ index ] ) {
						elem.style.display = "";
					}
				}
				if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
					values[ index ] = getDefaultDisplay( elem );
				}
			} else {
				if ( display !== "none" ) {
					values[ index ] = "none";
	
					// Remember what we're overwriting
					dataPriv.set( elem, "display", display );
				}
			}
		}
	
		// Set the display of the elements in a second loop to avoid constant reflow
		for ( index = 0; index < length; index++ ) {
			if ( values[ index ] != null ) {
				elements[ index ].style.display = values[ index ];
			}
		}
	
		return elements;
	}
	
	jQuery.fn.extend( {
		show: function() {
			return showHide( this, true );
		},
		hide: function() {
			return showHide( this );
		},
		toggle: function( state ) {
			if ( typeof state === "boolean" ) {
				return state ? this.show() : this.hide();
			}
	
			return this.each( function() {
				if ( isHiddenWithinTree( this ) ) {
					jQuery( this ).show();
				} else {
					jQuery( this ).hide();
				}
			} );
		}
	} );
	var rcheckableType = ( /^(?:checkbox|radio)$/i );
	
	var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
	
	var rscriptType = ( /^$|\/(?:java|ecma)script/i );
	
	
	
	// We have to close these tags to support XHTML (#13200)
	var wrapMap = {
	
		// Support: IE <=9 only
		option: [ 1, "<select multiple='multiple'>", "</select>" ],
	
		// XHTML parsers do not magically insert elements in the
		// same way that tag soup parsers do. So we cannot shorten
		// this by omitting <tbody> or other required elements.
		thead: [ 1, "<table>", "</table>" ],
		col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
	
		_default: [ 0, "", "" ]
	};
	
	// Support: IE <=9 only
	wrapMap.optgroup = wrapMap.option;
	
	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
	wrapMap.th = wrapMap.td;
	
	
	function getAll( context, tag ) {
	
		// Support: IE <=9 - 11 only
		// Use typeof to avoid zero-argument method invocation on host objects (#15151)
		var ret;
	
		if ( typeof context.getElementsByTagName !== "undefined" ) {
			ret = context.getElementsByTagName( tag || "*" );
	
		} else if ( typeof context.querySelectorAll !== "undefined" ) {
			ret = context.querySelectorAll( tag || "*" );
	
		} else {
			ret = [];
		}
	
		if ( tag === undefined || tag && nodeName( context, tag ) ) {
			return jQuery.merge( [ context ], ret );
		}
	
		return ret;
	}
	
	
	// Mark scripts as having already been evaluated
	function setGlobalEval( elems, refElements ) {
		var i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			dataPriv.set(
				elems[ i ],
				"globalEval",
				!refElements || dataPriv.get( refElements[ i ], "globalEval" )
			);
		}
	}
	
	
	var rhtml = /<|&#?\w+;/;
	
	function buildFragment( elems, context, scripts, selection, ignored ) {
		var elem, tmp, tag, wrap, contains, j,
			fragment = context.createDocumentFragment(),
			nodes = [],
			i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			elem = elems[ i ];
	
			if ( elem || elem === 0 ) {
	
				// Add nodes directly
				if ( jQuery.type( elem ) === "object" ) {
	
					// Support: Android <=4.0 only, PhantomJS 1 only
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
	
				// Convert non-html into a text node
				} else if ( !rhtml.test( elem ) ) {
					nodes.push( context.createTextNode( elem ) );
	
				// Convert html into DOM nodes
				} else {
					tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
	
					// Deserialize a standard representation
					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
					wrap = wrapMap[ tag ] || wrapMap._default;
					tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
	
					// Descend through wrappers to the right content
					j = wrap[ 0 ];
					while ( j-- ) {
						tmp = tmp.lastChild;
					}
	
					// Support: Android <=4.0 only, PhantomJS 1 only
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, tmp.childNodes );
	
					// Remember the top-level container
					tmp = fragment.firstChild;
	
					// Ensure the created nodes are orphaned (#12392)
					tmp.textContent = "";
				}
			}
		}
	
		// Remove wrapper from fragment
		fragment.textContent = "";
	
		i = 0;
		while ( ( elem = nodes[ i++ ] ) ) {
	
			// Skip elements already in the context collection (trac-4087)
			if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
				if ( ignored ) {
					ignored.push( elem );
				}
				continue;
			}
	
			contains = jQuery.contains( elem.ownerDocument, elem );
	
			// Append to fragment
			tmp = getAll( fragment.appendChild( elem ), "script" );
	
			// Preserve script evaluation history
			if ( contains ) {
				setGlobalEval( tmp );
			}
	
			// Capture executables
			if ( scripts ) {
				j = 0;
				while ( ( elem = tmp[ j++ ] ) ) {
					if ( rscriptType.test( elem.type || "" ) ) {
						scripts.push( elem );
					}
				}
			}
		}
	
		return fragment;
	}
	
	
	( function() {
		var fragment = document.createDocumentFragment(),
			div = fragment.appendChild( document.createElement( "div" ) ),
			input = document.createElement( "input" );
	
		// Support: Android 4.0 - 4.3 only
		// Check state lost if the name is set (#11217)
		// Support: Windows Web Apps (WWA)
		// `name` and `type` must use .setAttribute for WWA (#14901)
		input.setAttribute( "type", "radio" );
		input.setAttribute( "checked", "checked" );
		input.setAttribute( "name", "t" );
	
		div.appendChild( input );
	
		// Support: Android <=4.1 only
		// Older WebKit doesn't clone checked state correctly in fragments
		support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
	
		// Support: IE <=11 only
		// Make sure textarea (and checkbox) defaultValue is properly cloned
		div.innerHTML = "<textarea>x</textarea>";
		support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
	} )();
	var documentElement = document.documentElement;
	
	
	
	var
		rkeyEvent = /^key/,
		rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
		rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
	
	function returnTrue() {
		return true;
	}
	
	function returnFalse() {
		return false;
	}
	
	// Support: IE <=9 only
	// See #13393 for more info
	function safeActiveElement() {
		try {
			return document.activeElement;
		} catch ( err ) { }
	}
	
	function on( elem, types, selector, data, fn, one ) {
		var origFn, type;
	
		// Types can be a map of types/handlers
		if ( typeof types === "object" ) {
	
			// ( types-Object, selector, data )
			if ( typeof selector !== "string" ) {
	
				// ( types-Object, data )
				data = data || selector;
				selector = undefined;
			}
			for ( type in types ) {
				on( elem, type, selector, data, types[ type ], one );
			}
			return elem;
		}
	
		if ( data == null && fn == null ) {
	
			// ( types, fn )
			fn = selector;
			data = selector = undefined;
		} else if ( fn == null ) {
			if ( typeof selector === "string" ) {
	
				// ( types, selector, fn )
				fn = data;
				data = undefined;
			} else {
	
				// ( types, data, fn )
				fn = data;
				data = selector;
				selector = undefined;
			}
		}
		if ( fn === false ) {
			fn = returnFalse;
		} else if ( !fn ) {
			return elem;
		}
	
		if ( one === 1 ) {
			origFn = fn;
			fn = function( event ) {
	
				// Can use an empty set, since event contains the info
				jQuery().off( event );
				return origFn.apply( this, arguments );
			};
	
			// Use same guid so caller can remove using origFn
			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
		}
		return elem.each( function() {
			jQuery.event.add( this, types, fn, data, selector );
		} );
	}
	
	/*
	 * Helper functions for managing events -- not part of the public interface.
	 * Props to Dean Edwards' addEvent library for many of the ideas.
	 */
	jQuery.event = {
	
		global: {},
	
		add: function( elem, types, handler, data, selector ) {
	
			var handleObjIn, eventHandle, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.get( elem );
	
			// Don't attach events to noData or text/comment nodes (but allow plain objects)
			if ( !elemData ) {
				return;
			}
	
			// Caller can pass in an object of custom data in lieu of the handler
			if ( handler.handler ) {
				handleObjIn = handler;
				handler = handleObjIn.handler;
				selector = handleObjIn.selector;
			}
	
			// Ensure that invalid selectors throw exceptions at attach time
			// Evaluate against documentElement in case elem is a non-element node (e.g., document)
			if ( selector ) {
				jQuery.find.matchesSelector( documentElement, selector );
			}
	
			// Make sure that the handler has a unique ID, used to find/remove it later
			if ( !handler.guid ) {
				handler.guid = jQuery.guid++;
			}
	
			// Init the element's event structure and main handler, if this is the first
			if ( !( events = elemData.events ) ) {
				events = elemData.events = {};
			}
			if ( !( eventHandle = elemData.handle ) ) {
				eventHandle = elemData.handle = function( e ) {
	
					// Discard the second event of a jQuery.event.trigger() and
					// when an event is called after a page has unloaded
					return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
						jQuery.event.dispatch.apply( elem, arguments ) : undefined;
				};
			}
	
			// Handle multiple events separated by a space
			types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// There *must* be a type, no attaching namespace-only handlers
				if ( !type ) {
					continue;
				}
	
				// If event changes its type, use the special event handlers for the changed type
				special = jQuery.event.special[ type ] || {};
	
				// If selector defined, determine special event api type, otherwise given type
				type = ( selector ? special.delegateType : special.bindType ) || type;
	
				// Update special based on newly reset type
				special = jQuery.event.special[ type ] || {};
	
				// handleObj is passed to all event handlers
				handleObj = jQuery.extend( {
					type: type,
					origType: origType,
					data: data,
					handler: handler,
					guid: handler.guid,
					selector: selector,
					needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
					namespace: namespaces.join( "." )
				}, handleObjIn );
	
				// Init the event handler queue if we're the first
				if ( !( handlers = events[ type ] ) ) {
					handlers = events[ type ] = [];
					handlers.delegateCount = 0;
	
					// Only use addEventListener if the special events handler returns false
					if ( !special.setup ||
						special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
	
						if ( elem.addEventListener ) {
							elem.addEventListener( type, eventHandle );
						}
					}
				}
	
				if ( special.add ) {
					special.add.call( elem, handleObj );
	
					if ( !handleObj.handler.guid ) {
						handleObj.handler.guid = handler.guid;
					}
				}
	
				// Add to the element's handler list, delegates in front
				if ( selector ) {
					handlers.splice( handlers.delegateCount++, 0, handleObj );
				} else {
					handlers.push( handleObj );
				}
	
				// Keep track of which events have ever been used, for event optimization
				jQuery.event.global[ type ] = true;
			}
	
		},
	
		// Detach an event or set of events from an element
		remove: function( elem, types, handler, selector, mappedTypes ) {
	
			var j, origCount, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
	
			if ( !elemData || !( events = elemData.events ) ) {
				return;
			}
	
			// Once for each type.namespace in types; type may be omitted
			types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// Unbind all events (on this namespace, if provided) for the element
				if ( !type ) {
					for ( type in events ) {
						jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
					}
					continue;
				}
	
				special = jQuery.event.special[ type ] || {};
				type = ( selector ? special.delegateType : special.bindType ) || type;
				handlers = events[ type ] || [];
				tmp = tmp[ 2 ] &&
					new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
	
				// Remove matching events
				origCount = j = handlers.length;
				while ( j-- ) {
					handleObj = handlers[ j ];
	
					if ( ( mappedTypes || origType === handleObj.origType ) &&
						( !handler || handler.guid === handleObj.guid ) &&
						( !tmp || tmp.test( handleObj.namespace ) ) &&
						( !selector || selector === handleObj.selector ||
							selector === "**" && handleObj.selector ) ) {
						handlers.splice( j, 1 );
	
						if ( handleObj.selector ) {
							handlers.delegateCount--;
						}
						if ( special.remove ) {
							special.remove.call( elem, handleObj );
						}
					}
				}
	
				// Remove generic event handler if we removed something and no more handlers exist
				// (avoids potential for endless recursion during removal of special event handlers)
				if ( origCount && !handlers.length ) {
					if ( !special.teardown ||
						special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
	
						jQuery.removeEvent( elem, type, elemData.handle );
					}
	
					delete events[ type ];
				}
			}
	
			// Remove data and the expando if it's no longer used
			if ( jQuery.isEmptyObject( events ) ) {
				dataPriv.remove( elem, "handle events" );
			}
		},
	
		dispatch: function( nativeEvent ) {
	
			// Make a writable jQuery.Event from the native event object
			var event = jQuery.event.fix( nativeEvent );
	
			var i, j, ret, matched, handleObj, handlerQueue,
				args = new Array( arguments.length ),
				handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
				special = jQuery.event.special[ event.type ] || {};
	
			// Use the fix-ed jQuery.Event rather than the (read-only) native event
			args[ 0 ] = event;
	
			for ( i = 1; i < arguments.length; i++ ) {
				args[ i ] = arguments[ i ];
			}
	
			event.delegateTarget = this;
	
			// Call the preDispatch hook for the mapped type, and let it bail if desired
			if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
				return;
			}
	
			// Determine handlers
			handlerQueue = jQuery.event.handlers.call( this, event, handlers );
	
			// Run delegates first; they may want to stop propagation beneath us
			i = 0;
			while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
				event.currentTarget = matched.elem;
	
				j = 0;
				while ( ( handleObj = matched.handlers[ j++ ] ) &&
					!event.isImmediatePropagationStopped() ) {
	
					// Triggered event must either 1) have no namespace, or 2) have namespace(s)
					// a subset or equal to those in the bound event (both can have no namespace).
					if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
	
						event.handleObj = handleObj;
						event.data = handleObj.data;
	
						ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
							handleObj.handler ).apply( matched.elem, args );
	
						if ( ret !== undefined ) {
							if ( ( event.result = ret ) === false ) {
								event.preventDefault();
								event.stopPropagation();
							}
						}
					}
				}
			}
	
			// Call the postDispatch hook for the mapped type
			if ( special.postDispatch ) {
				special.postDispatch.call( this, event );
			}
	
			return event.result;
		},
	
		handlers: function( event, handlers ) {
			var i, handleObj, sel, matchedHandlers, matchedSelectors,
				handlerQueue = [],
				delegateCount = handlers.delegateCount,
				cur = event.target;
	
			// Find delegate handlers
			if ( delegateCount &&
	
				// Support: IE <=9
				// Black-hole SVG <use> instance trees (trac-13180)
				cur.nodeType &&
	
				// Support: Firefox <=42
				// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
				// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
				// Support: IE 11 only
				// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
				!( event.type === "click" && event.button >= 1 ) ) {
	
				for ( ; cur !== this; cur = cur.parentNode || this ) {
	
					// Don't check non-elements (#13208)
					// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
					if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
						matchedHandlers = [];
						matchedSelectors = {};
						for ( i = 0; i < delegateCount; i++ ) {
							handleObj = handlers[ i ];
	
							// Don't conflict with Object.prototype properties (#13203)
							sel = handleObj.selector + " ";
	
							if ( matchedSelectors[ sel ] === undefined ) {
								matchedSelectors[ sel ] = handleObj.needsContext ?
									jQuery( sel, this ).index( cur ) > -1 :
									jQuery.find( sel, this, null, [ cur ] ).length;
							}
							if ( matchedSelectors[ sel ] ) {
								matchedHandlers.push( handleObj );
							}
						}
						if ( matchedHandlers.length ) {
							handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
						}
					}
				}
			}
	
			// Add the remaining (directly-bound) handlers
			cur = this;
			if ( delegateCount < handlers.length ) {
				handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
			}
	
			return handlerQueue;
		},
	
		addProp: function( name, hook ) {
			Object.defineProperty( jQuery.Event.prototype, name, {
				enumerable: true,
				configurable: true,
	
				get: jQuery.isFunction( hook ) ?
					function() {
						if ( this.originalEvent ) {
								return hook( this.originalEvent );
						}
					} :
					function() {
						if ( this.originalEvent ) {
								return this.originalEvent[ name ];
						}
					},
	
				set: function( value ) {
					Object.defineProperty( this, name, {
						enumerable: true,
						configurable: true,
						writable: true,
						value: value
					} );
				}
			} );
		},
	
		fix: function( originalEvent ) {
			return originalEvent[ jQuery.expando ] ?
				originalEvent :
				new jQuery.Event( originalEvent );
		},
	
		special: {
			load: {
	
				// Prevent triggered image.load events from bubbling to window.load
				noBubble: true
			},
			focus: {
	
				// Fire native event if possible so blur/focus sequence is correct
				trigger: function() {
					if ( this !== safeActiveElement() && this.focus ) {
						this.focus();
						return false;
					}
				},
				delegateType: "focusin"
			},
			blur: {
				trigger: function() {
					if ( this === safeActiveElement() && this.blur ) {
						this.blur();
						return false;
					}
				},
				delegateType: "focusout"
			},
			click: {
	
				// For checkbox, fire native event so checked state will be right
				trigger: function() {
					if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
						this.click();
						return false;
					}
				},
	
				// For cross-browser consistency, don't fire native .click() on links
				_default: function( event ) {
					return nodeName( event.target, "a" );
				}
			},
	
			beforeunload: {
				postDispatch: function( event ) {
	
					// Support: Firefox 20+
					// Firefox doesn't alert if the returnValue field is not set.
					if ( event.result !== undefined && event.originalEvent ) {
						event.originalEvent.returnValue = event.result;
					}
				}
			}
		}
	};
	
	jQuery.removeEvent = function( elem, type, handle ) {
	
		// This "if" is needed for plain objects
		if ( elem.removeEventListener ) {
			elem.removeEventListener( type, handle );
		}
	};
	
	jQuery.Event = function( src, props ) {
	
		// Allow instantiation without the 'new' keyword
		if ( !( this instanceof jQuery.Event ) ) {
			return new jQuery.Event( src, props );
		}
	
		// Event object
		if ( src && src.type ) {
			this.originalEvent = src;
			this.type = src.type;
	
			// Events bubbling up the document may have been marked as prevented
			// by a handler lower down the tree; reflect the correct value.
			this.isDefaultPrevented = src.defaultPrevented ||
					src.defaultPrevented === undefined &&
	
					// Support: Android <=2.3 only
					src.returnValue === false ?
				returnTrue :
				returnFalse;
	
			// Create target properties
			// Support: Safari <=6 - 7 only
			// Target should not be a text node (#504, #13143)
			this.target = ( src.target && src.target.nodeType === 3 ) ?
				src.target.parentNode :
				src.target;
	
			this.currentTarget = src.currentTarget;
			this.relatedTarget = src.relatedTarget;
	
		// Event type
		} else {
			this.type = src;
		}
	
		// Put explicitly provided properties onto the event object
		if ( props ) {
			jQuery.extend( this, props );
		}
	
		// Create a timestamp if incoming event doesn't have one
		this.timeStamp = src && src.timeStamp || jQuery.now();
	
		// Mark it as fixed
		this[ jQuery.expando ] = true;
	};
	
	// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
	// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
	jQuery.Event.prototype = {
		constructor: jQuery.Event,
		isDefaultPrevented: returnFalse,
		isPropagationStopped: returnFalse,
		isImmediatePropagationStopped: returnFalse,
		isSimulated: false,
	
		preventDefault: function() {
			var e = this.originalEvent;
	
			this.isDefaultPrevented = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.preventDefault();
			}
		},
		stopPropagation: function() {
			var e = this.originalEvent;
	
			this.isPropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopPropagation();
			}
		},
		stopImmediatePropagation: function() {
			var e = this.originalEvent;
	
			this.isImmediatePropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopImmediatePropagation();
			}
	
			this.stopPropagation();
		}
	};
	
	// Includes all common event props including KeyEvent and MouseEvent specific props
	jQuery.each( {
		altKey: true,
		bubbles: true,
		cancelable: true,
		changedTouches: true,
		ctrlKey: true,
		detail: true,
		eventPhase: true,
		metaKey: true,
		pageX: true,
		pageY: true,
		shiftKey: true,
		view: true,
		"char": true,
		charCode: true,
		key: true,
		keyCode: true,
		button: true,
		buttons: true,
		clientX: true,
		clientY: true,
		offsetX: true,
		offsetY: true,
		pointerId: true,
		pointerType: true,
		screenX: true,
		screenY: true,
		targetTouches: true,
		toElement: true,
		touches: true,
	
		which: function( event ) {
			var button = event.button;
	
			// Add which for key events
			if ( event.which == null && rkeyEvent.test( event.type ) ) {
				return event.charCode != null ? event.charCode : event.keyCode;
			}
	
			// Add which for click: 1 === left; 2 === middle; 3 === right
			if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
				if ( button & 1 ) {
					return 1;
				}
	
				if ( button & 2 ) {
					return 3;
				}
	
				if ( button & 4 ) {
					return 2;
				}
	
				return 0;
			}
	
			return event.which;
		}
	}, jQuery.event.addProp );
	
	// Create mouseenter/leave events using mouseover/out and event-time checks
	// so that event delegation works in jQuery.
	// Do the same for pointerenter/pointerleave and pointerover/pointerout
	//
	// Support: Safari 7 only
	// Safari sends mouseenter too often; see:
	// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
	// for the description of the bug (it existed in older Chrome versions as well).
	jQuery.each( {
		mouseenter: "mouseover",
		mouseleave: "mouseout",
		pointerenter: "pointerover",
		pointerleave: "pointerout"
	}, function( orig, fix ) {
		jQuery.event.special[ orig ] = {
			delegateType: fix,
			bindType: fix,
	
			handle: function( event ) {
				var ret,
					target = this,
					related = event.relatedTarget,
					handleObj = event.handleObj;
	
				// For mouseenter/leave call the handler if related is outside the target.
				// NB: No relatedTarget if the mouse left/entered the browser window
				if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
					event.type = handleObj.origType;
					ret = handleObj.handler.apply( this, arguments );
					event.type = fix;
				}
				return ret;
			}
		};
	} );
	
	jQuery.fn.extend( {
	
		on: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn );
		},
		one: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn, 1 );
		},
		off: function( types, selector, fn ) {
			var handleObj, type;
			if ( types && types.preventDefault && types.handleObj ) {
	
				// ( event )  dispatched jQuery.Event
				handleObj = types.handleObj;
				jQuery( types.delegateTarget ).off(
					handleObj.namespace ?
						handleObj.origType + "." + handleObj.namespace :
						handleObj.origType,
					handleObj.selector,
					handleObj.handler
				);
				return this;
			}
			if ( typeof types === "object" ) {
	
				// ( types-object [, selector] )
				for ( type in types ) {
					this.off( type, selector, types[ type ] );
				}
				return this;
			}
			if ( selector === false || typeof selector === "function" ) {
	
				// ( types [, fn] )
				fn = selector;
				selector = undefined;
			}
			if ( fn === false ) {
				fn = returnFalse;
			}
			return this.each( function() {
				jQuery.event.remove( this, types, fn, selector );
			} );
		}
	} );
	
	
	var
	
		/* eslint-disable max-len */
	
		// See https://github.com/eslint/eslint/issues/3229
		rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
	
		/* eslint-enable */
	
		// Support: IE <=10 - 11, Edge 12 - 13
		// In IE/Edge using regex groups here causes severe slowdowns.
		// See https://connect.microsoft.com/IE/feedback/details/1736512/
		rnoInnerhtml = /<script|<style|<link/i,
	
		// checked="checked" or checked
		rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
		rscriptTypeMasked = /^true\/(.*)/,
		rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
	
	// Prefer a tbody over its parent table for containing new rows
	function manipulationTarget( elem, content ) {
		if ( nodeName( elem, "table" ) &&
			nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
	
			return jQuery( ">tbody", elem )[ 0 ] || elem;
		}
	
		return elem;
	}
	
	// Replace/restore the type attribute of script elements for safe DOM manipulation
	function disableScript( elem ) {
		elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
		return elem;
	}
	function restoreScript( elem ) {
		var match = rscriptTypeMasked.exec( elem.type );
	
		if ( match ) {
			elem.type = match[ 1 ];
		} else {
			elem.removeAttribute( "type" );
		}
	
		return elem;
	}
	
	function cloneCopyEvent( src, dest ) {
		var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
	
		if ( dest.nodeType !== 1 ) {
			return;
		}
	
		// 1. Copy private data: events, handlers, etc.
		if ( dataPriv.hasData( src ) ) {
			pdataOld = dataPriv.access( src );
			pdataCur = dataPriv.set( dest, pdataOld );
			events = pdataOld.events;
	
			if ( events ) {
				delete pdataCur.handle;
				pdataCur.events = {};
	
				for ( type in events ) {
					for ( i = 0, l = events[ type ].length; i < l; i++ ) {
						jQuery.event.add( dest, type, events[ type ][ i ] );
					}
				}
			}
		}
	
		// 2. Copy user data
		if ( dataUser.hasData( src ) ) {
			udataOld = dataUser.access( src );
			udataCur = jQuery.extend( {}, udataOld );
	
			dataUser.set( dest, udataCur );
		}
	}
	
	// Fix IE bugs, see support tests
	function fixInput( src, dest ) {
		var nodeName = dest.nodeName.toLowerCase();
	
		// Fails to persist the checked state of a cloned checkbox or radio button.
		if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
			dest.checked = src.checked;
	
		// Fails to return the selected option to the default selected state when cloning options
		} else if ( nodeName === "input" || nodeName === "textarea" ) {
			dest.defaultValue = src.defaultValue;
		}
	}
	
	function domManip( collection, args, callback, ignored ) {
	
		// Flatten any nested arrays
		args = concat.apply( [], args );
	
		var fragment, first, scripts, hasScripts, node, doc,
			i = 0,
			l = collection.length,
			iNoClone = l - 1,
			value = args[ 0 ],
			isFunction = jQuery.isFunction( value );
	
		// We can't cloneNode fragments that contain checked, in WebKit
		if ( isFunction ||
				( l > 1 && typeof value === "string" &&
					!support.checkClone && rchecked.test( value ) ) ) {
			return collection.each( function( index ) {
				var self = collection.eq( index );
				if ( isFunction ) {
					args[ 0 ] = value.call( this, index, self.html() );
				}
				domManip( self, args, callback, ignored );
			} );
		}
	
		if ( l ) {
			fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
			first = fragment.firstChild;
	
			if ( fragment.childNodes.length === 1 ) {
				fragment = first;
			}
	
			// Require either new content or an interest in ignored elements to invoke the callback
			if ( first || ignored ) {
				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
				hasScripts = scripts.length;
	
				// Use the original fragment for the last item
				// instead of the first because it can end up
				// being emptied incorrectly in certain situations (#8070).
				for ( ; i < l; i++ ) {
					node = fragment;
	
					if ( i !== iNoClone ) {
						node = jQuery.clone( node, true, true );
	
						// Keep references to cloned scripts for later restoration
						if ( hasScripts ) {
	
							// Support: Android <=4.0 only, PhantomJS 1 only
							// push.apply(_, arraylike) throws on ancient WebKit
							jQuery.merge( scripts, getAll( node, "script" ) );
						}
					}
	
					callback.call( collection[ i ], node, i );
				}
	
				if ( hasScripts ) {
					doc = scripts[ scripts.length - 1 ].ownerDocument;
	
					// Reenable scripts
					jQuery.map( scripts, restoreScript );
	
					// Evaluate executable scripts on first document insertion
					for ( i = 0; i < hasScripts; i++ ) {
						node = scripts[ i ];
						if ( rscriptType.test( node.type || "" ) &&
							!dataPriv.access( node, "globalEval" ) &&
							jQuery.contains( doc, node ) ) {
	
							if ( node.src ) {
	
								// Optional AJAX dependency, but won't run scripts if not present
								if ( jQuery._evalUrl ) {
									jQuery._evalUrl( node.src );
								}
							} else {
								DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
							}
						}
					}
				}
			}
		}
	
		return collection;
	}
	
	function remove( elem, selector, keepData ) {
		var node,
			nodes = selector ? jQuery.filter( selector, elem ) : elem,
			i = 0;
	
		for ( ; ( node = nodes[ i ] ) != null; i++ ) {
			if ( !keepData && node.nodeType === 1 ) {
				jQuery.cleanData( getAll( node ) );
			}
	
			if ( node.parentNode ) {
				if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
					setGlobalEval( getAll( node, "script" ) );
				}
				node.parentNode.removeChild( node );
			}
		}
	
		return elem;
	}
	
	jQuery.extend( {
		htmlPrefilter: function( html ) {
			return html.replace( rxhtmlTag, "<$1></$2>" );
		},
	
		clone: function( elem, dataAndEvents, deepDataAndEvents ) {
			var i, l, srcElements, destElements,
				clone = elem.cloneNode( true ),
				inPage = jQuery.contains( elem.ownerDocument, elem );
	
			// Fix IE cloning issues
			if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
					!jQuery.isXMLDoc( elem ) ) {
	
				// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
				destElements = getAll( clone );
				srcElements = getAll( elem );
	
				for ( i = 0, l = srcElements.length; i < l; i++ ) {
					fixInput( srcElements[ i ], destElements[ i ] );
				}
			}
	
			// Copy the events from the original to the clone
			if ( dataAndEvents ) {
				if ( deepDataAndEvents ) {
					srcElements = srcElements || getAll( elem );
					destElements = destElements || getAll( clone );
	
					for ( i = 0, l = srcElements.length; i < l; i++ ) {
						cloneCopyEvent( srcElements[ i ], destElements[ i ] );
					}
				} else {
					cloneCopyEvent( elem, clone );
				}
			}
	
			// Preserve script evaluation history
			destElements = getAll( clone, "script" );
			if ( destElements.length > 0 ) {
				setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
			}
	
			// Return the cloned set
			return clone;
		},
	
		cleanData: function( elems ) {
			var data, elem, type,
				special = jQuery.event.special,
				i = 0;
	
			for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
				if ( acceptData( elem ) ) {
					if ( ( data = elem[ dataPriv.expando ] ) ) {
						if ( data.events ) {
							for ( type in data.events ) {
								if ( special[ type ] ) {
									jQuery.event.remove( elem, type );
	
								// This is a shortcut to avoid jQuery.event.remove's overhead
								} else {
									jQuery.removeEvent( elem, type, data.handle );
								}
							}
						}
	
						// Support: Chrome <=35 - 45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataPriv.expando ] = undefined;
					}
					if ( elem[ dataUser.expando ] ) {
	
						// Support: Chrome <=35 - 45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataUser.expando ] = undefined;
					}
				}
			}
		}
	} );
	
	jQuery.fn.extend( {
		detach: function( selector ) {
			return remove( this, selector, true );
		},
	
		remove: function( selector ) {
			return remove( this, selector );
		},
	
		text: function( value ) {
			return access( this, function( value ) {
				return value === undefined ?
					jQuery.text( this ) :
					this.empty().each( function() {
						if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
							this.textContent = value;
						}
					} );
			}, null, value, arguments.length );
		},
	
		append: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.appendChild( elem );
				}
			} );
		},
	
		prepend: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.insertBefore( elem, target.firstChild );
				}
			} );
		},
	
		before: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this );
				}
			} );
		},
	
		after: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this.nextSibling );
				}
			} );
		},
	
		empty: function() {
			var elem,
				i = 0;
	
			for ( ; ( elem = this[ i ] ) != null; i++ ) {
				if ( elem.nodeType === 1 ) {
	
					// Prevent memory leaks
					jQuery.cleanData( getAll( elem, false ) );
	
					// Remove any remaining nodes
					elem.textContent = "";
				}
			}
	
			return this;
		},
	
		clone: function( dataAndEvents, deepDataAndEvents ) {
			dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
			deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
	
			return this.map( function() {
				return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
			} );
		},
	
		html: function( value ) {
			return access( this, function( value ) {
				var elem = this[ 0 ] || {},
					i = 0,
					l = this.length;
	
				if ( value === undefined && elem.nodeType === 1 ) {
					return elem.innerHTML;
				}
	
				// See if we can take a shortcut and just use innerHTML
				if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
					!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
	
					value = jQuery.htmlPrefilter( value );
	
					try {
						for ( ; i < l; i++ ) {
							elem = this[ i ] || {};
	
							// Remove element nodes and prevent memory leaks
							if ( elem.nodeType === 1 ) {
								jQuery.cleanData( getAll( elem, false ) );
								elem.innerHTML = value;
							}
						}
	
						elem = 0;
	
					// If using innerHTML throws an exception, use the fallback method
					} catch ( e ) {}
				}
	
				if ( elem ) {
					this.empty().append( value );
				}
			}, null, value, arguments.length );
		},
	
		replaceWith: function() {
			var ignored = [];
	
			// Make the changes, replacing each non-ignored context element with the new content
			return domManip( this, arguments, function( elem ) {
				var parent = this.parentNode;
	
				if ( jQuery.inArray( this, ignored ) < 0 ) {
					jQuery.cleanData( getAll( this ) );
					if ( parent ) {
						parent.replaceChild( elem, this );
					}
				}
	
			// Force callback invocation
			}, ignored );
		}
	} );
	
	jQuery.each( {
		appendTo: "append",
		prependTo: "prepend",
		insertBefore: "before",
		insertAfter: "after",
		replaceAll: "replaceWith"
	}, function( name, original ) {
		jQuery.fn[ name ] = function( selector ) {
			var elems,
				ret = [],
				insert = jQuery( selector ),
				last = insert.length - 1,
				i = 0;
	
			for ( ; i <= last; i++ ) {
				elems = i === last ? this : this.clone( true );
				jQuery( insert[ i ] )[ original ]( elems );
	
				// Support: Android <=4.0 only, PhantomJS 1 only
				// .get() because push.apply(_, arraylike) throws on ancient WebKit
				push.apply( ret, elems.get() );
			}
	
			return this.pushStack( ret );
		};
	} );
	var rmargin = ( /^margin/ );
	
	var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
	
	var getStyles = function( elem ) {
	
			// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
			// IE throws on elements created in popups
			// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
			var view = elem.ownerDocument.defaultView;
	
			if ( !view || !view.opener ) {
				view = window;
			}
	
			return view.getComputedStyle( elem );
		};
	
	
	
	( function() {
	
		// Executing both pixelPosition & boxSizingReliable tests require only one layout
		// so they're executed at the same time to save the second computation.
		function computeStyleTests() {
	
			// This is a singleton, we need to execute it only once
			if ( !div ) {
				return;
			}
	
			div.style.cssText =
				"box-sizing:border-box;" +
				"position:relative;display:block;" +
				"margin:auto;border:1px;padding:1px;" +
				"top:1%;width:50%";
			div.innerHTML = "";
			documentElement.appendChild( container );
	
			var divStyle = window.getComputedStyle( div );
			pixelPositionVal = divStyle.top !== "1%";
	
			// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
			reliableMarginLeftVal = divStyle.marginLeft === "2px";
			boxSizingReliableVal = divStyle.width === "4px";
	
			// Support: Android 4.0 - 4.3 only
			// Some styles come back with percentage values, even though they shouldn't
			div.style.marginRight = "50%";
			pixelMarginRightVal = divStyle.marginRight === "4px";
	
			documentElement.removeChild( container );
	
			// Nullify the div so it wouldn't be stored in the memory and
			// it will also be a sign that checks already performed
			div = null;
		}
	
		var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
			container = document.createElement( "div" ),
			div = document.createElement( "div" );
	
		// Finish early in limited (non-browser) environments
		if ( !div.style ) {
			return;
		}
	
		// Support: IE <=9 - 11 only
		// Style of cloned element affects source element cloned (#8908)
		div.style.backgroundClip = "content-box";
		div.cloneNode( true ).style.backgroundClip = "";
		support.clearCloneStyle = div.style.backgroundClip === "content-box";
	
		container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
			"padding:0;margin-top:1px;position:absolute";
		container.appendChild( div );
	
		jQuery.extend( support, {
			pixelPosition: function() {
				computeStyleTests();
				return pixelPositionVal;
			},
			boxSizingReliable: function() {
				computeStyleTests();
				return boxSizingReliableVal;
			},
			pixelMarginRight: function() {
				computeStyleTests();
				return pixelMarginRightVal;
			},
			reliableMarginLeft: function() {
				computeStyleTests();
				return reliableMarginLeftVal;
			}
		} );
	} )();
	
	
	function curCSS( elem, name, computed ) {
		var width, minWidth, maxWidth, ret,
	
			// Support: Firefox 51+
			// Retrieving style before computed somehow
			// fixes an issue with getting wrong values
			// on detached elements
			style = elem.style;
	
		computed = computed || getStyles( elem );
	
		// getPropertyValue is needed for:
		//   .css('filter') (IE 9 only, #12537)
		//   .css('--customProperty) (#3144)
		if ( computed ) {
			ret = computed.getPropertyValue( name ) || computed[ name ];
	
			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
				ret = jQuery.style( elem, name );
			}
	
			// A tribute to the "awesome hack by Dean Edwards"
			// Android Browser returns percentage for some values,
			// but width seems to be reliably pixels.
			// This is against the CSSOM draft spec:
			// https://drafts.csswg.org/cssom/#resolved-values
			if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
	
				// Remember the original values
				width = style.width;
				minWidth = style.minWidth;
				maxWidth = style.maxWidth;
	
				// Put in the new values to get a computed value out
				style.minWidth = style.maxWidth = style.width = ret;
				ret = computed.width;
	
				// Revert the changed values
				style.width = width;
				style.minWidth = minWidth;
				style.maxWidth = maxWidth;
			}
		}
	
		return ret !== undefined ?
	
			// Support: IE <=9 - 11 only
			// IE returns zIndex value as an integer.
			ret + "" :
			ret;
	}
	
	
	function addGetHookIf( conditionFn, hookFn ) {
	
		// Define the hook, we'll check on the first run if it's really needed.
		return {
			get: function() {
				if ( conditionFn() ) {
	
					// Hook not needed (or it's not possible to use it due
					// to missing dependency), remove it.
					delete this.get;
					return;
				}
	
				// Hook needed; redefine it so that the support test is not executed again.
				return ( this.get = hookFn ).apply( this, arguments );
			}
		};
	}
	
	
	var
	
		// Swappable if display is none or starts with table
		// except "table", "table-cell", or "table-caption"
		// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
		rdisplayswap = /^(none|table(?!-c[ea]).+)/,
		rcustomProp = /^--/,
		cssShow = { position: "absolute", visibility: "hidden", display: "block" },
		cssNormalTransform = {
			letterSpacing: "0",
			fontWeight: "400"
		},
	
		cssPrefixes = [ "Webkit", "Moz", "ms" ],
		emptyStyle = document.createElement( "div" ).style;
	
	// Return a css property mapped to a potentially vendor prefixed property
	function vendorPropName( name ) {
	
		// Shortcut for names that are not vendor prefixed
		if ( name in emptyStyle ) {
			return name;
		}
	
		// Check for vendor prefixed names
		var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
			i = cssPrefixes.length;
	
		while ( i-- ) {
			name = cssPrefixes[ i ] + capName;
			if ( name in emptyStyle ) {
				return name;
			}
		}
	}
	
	// Return a property mapped along what jQuery.cssProps suggests or to
	// a vendor prefixed property.
	function finalPropName( name ) {
		var ret = jQuery.cssProps[ name ];
		if ( !ret ) {
			ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
		}
		return ret;
	}
	
	function setPositiveNumber( elem, value, subtract ) {
	
		// Any relative (+/-) values have already been
		// normalized at this point
		var matches = rcssNum.exec( value );
		return matches ?
	
			// Guard against undefined "subtract", e.g., when used as in cssHooks
			Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
			value;
	}
	
	function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
		var i,
			val = 0;
	
		// If we already have the right measurement, avoid augmentation
		if ( extra === ( isBorderBox ? "border" : "content" ) ) {
			i = 4;
	
		// Otherwise initialize for horizontal or vertical properties
		} else {
			i = name === "width" ? 1 : 0;
		}
	
		for ( ; i < 4; i += 2 ) {
	
			// Both box models exclude margin, so add it if we want it
			if ( extra === "margin" ) {
				val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
			}
	
			if ( isBorderBox ) {
	
				// border-box includes padding, so remove it if we want content
				if ( extra === "content" ) {
					val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
				}
	
				// At this point, extra isn't border nor margin, so remove border
				if ( extra !== "margin" ) {
					val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			} else {
	
				// At this point, extra isn't content, so add padding
				val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
	
				// At this point, extra isn't content nor padding, so add border
				if ( extra !== "padding" ) {
					val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			}
		}
	
		return val;
	}
	
	function getWidthOrHeight( elem, name, extra ) {
	
		// Start with computed style
		var valueIsBorderBox,
			styles = getStyles( elem ),
			val = curCSS( elem, name, styles ),
			isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
	
		// Computed unit is not pixels. Stop here and return.
		if ( rnumnonpx.test( val ) ) {
			return val;
		}
	
		// Check for style in case a browser which returns unreliable values
		// for getComputedStyle silently falls back to the reliable elem.style
		valueIsBorderBox = isBorderBox &&
			( support.boxSizingReliable() || val === elem.style[ name ] );
	
		// Fall back to offsetWidth/Height when value is "auto"
		// This happens for inline elements with no explicit setting (gh-3571)
		if ( val === "auto" ) {
			val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
		}
	
		// Normalize "", auto, and prepare for extra
		val = parseFloat( val ) || 0;
	
		// Use the active box-sizing model to add/subtract irrelevant styles
		return ( val +
			augmentWidthOrHeight(
				elem,
				name,
				extra || ( isBorderBox ? "border" : "content" ),
				valueIsBorderBox,
				styles
			)
		) + "px";
	}
	
	jQuery.extend( {
	
		// Add in style property hooks for overriding the default
		// behavior of getting and setting a style property
		cssHooks: {
			opacity: {
				get: function( elem, computed ) {
					if ( computed ) {
	
						// We should always get a number back from opacity
						var ret = curCSS( elem, "opacity" );
						return ret === "" ? "1" : ret;
					}
				}
			}
		},
	
		// Don't automatically add "px" to these possibly-unitless properties
		cssNumber: {
			"animationIterationCount": true,
			"columnCount": true,
			"fillOpacity": true,
			"flexGrow": true,
			"flexShrink": true,
			"fontWeight": true,
			"lineHeight": true,
			"opacity": true,
			"order": true,
			"orphans": true,
			"widows": true,
			"zIndex": true,
			"zoom": true
		},
	
		// Add in properties whose names you wish to fix before
		// setting or getting the value
		cssProps: {
			"float": "cssFloat"
		},
	
		// Get and set the style property on a DOM Node
		style: function( elem, name, value, extra ) {
	
			// Don't set styles on text and comment nodes
			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
				return;
			}
	
			// Make sure that we're working with the right name
			var ret, type, hooks,
				origName = jQuery.camelCase( name ),
				isCustomProp = rcustomProp.test( name ),
				style = elem.style;
	
			// Make sure that we're working with the right name. We don't
			// want to query the value if it is a CSS custom property
			// since they are user-defined.
			if ( !isCustomProp ) {
				name = finalPropName( origName );
			}
	
			// Gets hook for the prefixed version, then unprefixed version
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// Check if we're setting a value
			if ( value !== undefined ) {
				type = typeof value;
	
				// Convert "+=" or "-=" to relative numbers (#7345)
				if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
					value = adjustCSS( elem, name, ret );
	
					// Fixes bug #9237
					type = "number";
				}
	
				// Make sure that null and NaN values aren't set (#7116)
				if ( value == null || value !== value ) {
					return;
				}
	
				// If a number was passed in, add the unit (except for certain CSS properties)
				if ( type === "number" ) {
					value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
				}
	
				// background-* props affect original clone's values
				if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
					style[ name ] = "inherit";
				}
	
				// If a hook was provided, use that value, otherwise just set the specified value
				if ( !hooks || !( "set" in hooks ) ||
					( value = hooks.set( elem, value, extra ) ) !== undefined ) {
	
					if ( isCustomProp ) {
						style.setProperty( name, value );
					} else {
						style[ name ] = value;
					}
				}
	
			} else {
	
				// If a hook was provided get the non-computed value from there
				if ( hooks && "get" in hooks &&
					( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
	
					return ret;
				}
	
				// Otherwise just get the value from the style object
				return style[ name ];
			}
		},
	
		css: function( elem, name, extra, styles ) {
			var val, num, hooks,
				origName = jQuery.camelCase( name ),
				isCustomProp = rcustomProp.test( name );
	
			// Make sure that we're working with the right name. We don't
			// want to modify the value if it is a CSS custom property
			// since they are user-defined.
			if ( !isCustomProp ) {
				name = finalPropName( origName );
			}
	
			// Try prefixed name followed by the unprefixed name
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// If a hook was provided get the computed value from there
			if ( hooks && "get" in hooks ) {
				val = hooks.get( elem, true, extra );
			}
	
			// Otherwise, if a way to get the computed value exists, use that
			if ( val === undefined ) {
				val = curCSS( elem, name, styles );
			}
	
			// Convert "normal" to computed value
			if ( val === "normal" && name in cssNormalTransform ) {
				val = cssNormalTransform[ name ];
			}
	
			// Make numeric if forced or a qualifier was provided and val looks numeric
			if ( extra === "" || extra ) {
				num = parseFloat( val );
				return extra === true || isFinite( num ) ? num || 0 : val;
			}
	
			return val;
		}
	} );
	
	jQuery.each( [ "height", "width" ], function( i, name ) {
		jQuery.cssHooks[ name ] = {
			get: function( elem, computed, extra ) {
				if ( computed ) {
	
					// Certain elements can have dimension info if we invisibly show them
					// but it must have a current display style that would benefit
					return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
	
						// Support: Safari 8+
						// Table columns in Safari have non-zero offsetWidth & zero
						// getBoundingClientRect().width unless display is changed.
						// Support: IE <=11 only
						// Running getBoundingClientRect on a disconnected node
						// in IE throws an error.
						( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
							swap( elem, cssShow, function() {
								return getWidthOrHeight( elem, name, extra );
							} ) :
							getWidthOrHeight( elem, name, extra );
				}
			},
	
			set: function( elem, value, extra ) {
				var matches,
					styles = extra && getStyles( elem ),
					subtract = extra && augmentWidthOrHeight(
						elem,
						name,
						extra,
						jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
						styles
					);
	
				// Convert to pixels if value adjustment is needed
				if ( subtract && ( matches = rcssNum.exec( value ) ) &&
					( matches[ 3 ] || "px" ) !== "px" ) {
	
					elem.style[ name ] = value;
					value = jQuery.css( elem, name );
				}
	
				return setPositiveNumber( elem, value, subtract );
			}
		};
	} );
	
	jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
		function( elem, computed ) {
			if ( computed ) {
				return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
					elem.getBoundingClientRect().left -
						swap( elem, { marginLeft: 0 }, function() {
							return elem.getBoundingClientRect().left;
						} )
					) + "px";
			}
		}
	);
	
	// These hooks are used by animate to expand properties
	jQuery.each( {
		margin: "",
		padding: "",
		border: "Width"
	}, function( prefix, suffix ) {
		jQuery.cssHooks[ prefix + suffix ] = {
			expand: function( value ) {
				var i = 0,
					expanded = {},
	
					// Assumes a single number if not a string
					parts = typeof value === "string" ? value.split( " " ) : [ value ];
	
				for ( ; i < 4; i++ ) {
					expanded[ prefix + cssExpand[ i ] + suffix ] =
						parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
				}
	
				return expanded;
			}
		};
	
		if ( !rmargin.test( prefix ) ) {
			jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
		}
	} );
	
	jQuery.fn.extend( {
		css: function( name, value ) {
			return access( this, function( elem, name, value ) {
				var styles, len,
					map = {},
					i = 0;
	
				if ( Array.isArray( name ) ) {
					styles = getStyles( elem );
					len = name.length;
	
					for ( ; i < len; i++ ) {
						map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
					}
	
					return map;
				}
	
				return value !== undefined ?
					jQuery.style( elem, name, value ) :
					jQuery.css( elem, name );
			}, name, value, arguments.length > 1 );
		}
	} );
	
	
	function Tween( elem, options, prop, end, easing ) {
		return new Tween.prototype.init( elem, options, prop, end, easing );
	}
	jQuery.Tween = Tween;
	
	Tween.prototype = {
		constructor: Tween,
		init: function( elem, options, prop, end, easing, unit ) {
			this.elem = elem;
			this.prop = prop;
			this.easing = easing || jQuery.easing._default;
			this.options = options;
			this.start = this.now = this.cur();
			this.end = end;
			this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
		},
		cur: function() {
			var hooks = Tween.propHooks[ this.prop ];
	
			return hooks && hooks.get ?
				hooks.get( this ) :
				Tween.propHooks._default.get( this );
		},
		run: function( percent ) {
			var eased,
				hooks = Tween.propHooks[ this.prop ];
	
			if ( this.options.duration ) {
				this.pos = eased = jQuery.easing[ this.easing ](
					percent, this.options.duration * percent, 0, 1, this.options.duration
				);
			} else {
				this.pos = eased = percent;
			}
			this.now = ( this.end - this.start ) * eased + this.start;
	
			if ( this.options.step ) {
				this.options.step.call( this.elem, this.now, this );
			}
	
			if ( hooks && hooks.set ) {
				hooks.set( this );
			} else {
				Tween.propHooks._default.set( this );
			}
			return this;
		}
	};
	
	Tween.prototype.init.prototype = Tween.prototype;
	
	Tween.propHooks = {
		_default: {
			get: function( tween ) {
				var result;
	
				// Use a property on the element directly when it is not a DOM element,
				// or when there is no matching style property that exists.
				if ( tween.elem.nodeType !== 1 ||
					tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
					return tween.elem[ tween.prop ];
				}
	
				// Passing an empty string as a 3rd parameter to .css will automatically
				// attempt a parseFloat and fallback to a string if the parse fails.
				// Simple values such as "10px" are parsed to Float;
				// complex values such as "rotate(1rad)" are returned as-is.
				result = jQuery.css( tween.elem, tween.prop, "" );
	
				// Empty strings, null, undefined and "auto" are converted to 0.
				return !result || result === "auto" ? 0 : result;
			},
			set: function( tween ) {
	
				// Use step hook for back compat.
				// Use cssHook if its there.
				// Use .style if available and use plain properties where available.
				if ( jQuery.fx.step[ tween.prop ] ) {
					jQuery.fx.step[ tween.prop ]( tween );
				} else if ( tween.elem.nodeType === 1 &&
					( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
						jQuery.cssHooks[ tween.prop ] ) ) {
					jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
				} else {
					tween.elem[ tween.prop ] = tween.now;
				}
			}
		}
	};
	
	// Support: IE <=9 only
	// Panic based approach to setting things on disconnected nodes
	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
		set: function( tween ) {
			if ( tween.elem.nodeType && tween.elem.parentNode ) {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	};
	
	jQuery.easing = {
		linear: function( p ) {
			return p;
		},
		swing: function( p ) {
			return 0.5 - Math.cos( p * Math.PI ) / 2;
		},
		_default: "swing"
	};
	
	jQuery.fx = Tween.prototype.init;
	
	// Back compat <1.8 extension point
	jQuery.fx.step = {};
	
	
	
	
	var
		fxNow, inProgress,
		rfxtypes = /^(?:toggle|show|hide)$/,
		rrun = /queueHooks$/;
	
	function schedule() {
		if ( inProgress ) {
			if ( document.hidden === false && window.requestAnimationFrame ) {
				window.requestAnimationFrame( schedule );
			} else {
				window.setTimeout( schedule, jQuery.fx.interval );
			}
	
			jQuery.fx.tick();
		}
	}
	
	// Animations created synchronously will run synchronously
	function createFxNow() {
		window.setTimeout( function() {
			fxNow = undefined;
		} );
		return ( fxNow = jQuery.now() );
	}
	
	// Generate parameters to create a standard animation
	function genFx( type, includeWidth ) {
		var which,
			i = 0,
			attrs = { height: type };
	
		// If we include width, step value is 1 to do all cssExpand values,
		// otherwise step value is 2 to skip over Left and Right
		includeWidth = includeWidth ? 1 : 0;
		for ( ; i < 4; i += 2 - includeWidth ) {
			which = cssExpand[ i ];
			attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
		}
	
		if ( includeWidth ) {
			attrs.opacity = attrs.width = type;
		}
	
		return attrs;
	}
	
	function createTween( value, prop, animation ) {
		var tween,
			collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
			index = 0,
			length = collection.length;
		for ( ; index < length; index++ ) {
			if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
	
				// We're done with this property
				return tween;
			}
		}
	}
	
	function defaultPrefilter( elem, props, opts ) {
		var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
			isBox = "width" in props || "height" in props,
			anim = this,
			orig = {},
			style = elem.style,
			hidden = elem.nodeType && isHiddenWithinTree( elem ),
			dataShow = dataPriv.get( elem, "fxshow" );
	
		// Queue-skipping animations hijack the fx hooks
		if ( !opts.queue ) {
			hooks = jQuery._queueHooks( elem, "fx" );
			if ( hooks.unqueued == null ) {
				hooks.unqueued = 0;
				oldfire = hooks.empty.fire;
				hooks.empty.fire = function() {
					if ( !hooks.unqueued ) {
						oldfire();
					}
				};
			}
			hooks.unqueued++;
	
			anim.always( function() {
	
				// Ensure the complete handler is called before this completes
				anim.always( function() {
					hooks.unqueued--;
					if ( !jQuery.queue( elem, "fx" ).length ) {
						hooks.empty.fire();
					}
				} );
			} );
		}
	
		// Detect show/hide animations
		for ( prop in props ) {
			value = props[ prop ];
			if ( rfxtypes.test( value ) ) {
				delete props[ prop ];
				toggle = toggle || value === "toggle";
				if ( value === ( hidden ? "hide" : "show" ) ) {
	
					// Pretend to be hidden if this is a "show" and
					// there is still data from a stopped show/hide
					if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
						hidden = true;
	
					// Ignore all other no-op show/hide data
					} else {
						continue;
					}
				}
				orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
			}
		}
	
		// Bail out if this is a no-op like .hide().hide()
		propTween = !jQuery.isEmptyObject( props );
		if ( !propTween && jQuery.isEmptyObject( orig ) ) {
			return;
		}
	
		// Restrict "overflow" and "display" styles during box animations
		if ( isBox && elem.nodeType === 1 ) {
	
			// Support: IE <=9 - 11, Edge 12 - 13
			// Record all 3 overflow attributes because IE does not infer the shorthand
			// from identically-valued overflowX and overflowY
			opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
	
			// Identify a display type, preferring old show/hide data over the CSS cascade
			restoreDisplay = dataShow && dataShow.display;
			if ( restoreDisplay == null ) {
				restoreDisplay = dataPriv.get( elem, "display" );
			}
			display = jQuery.css( elem, "display" );
			if ( display === "none" ) {
				if ( restoreDisplay ) {
					display = restoreDisplay;
				} else {
	
					// Get nonempty value(s) by temporarily forcing visibility
					showHide( [ elem ], true );
					restoreDisplay = elem.style.display || restoreDisplay;
					display = jQuery.css( elem, "display" );
					showHide( [ elem ] );
				}
			}
	
			// Animate inline elements as inline-block
			if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
				if ( jQuery.css( elem, "float" ) === "none" ) {
	
					// Restore the original display value at the end of pure show/hide animations
					if ( !propTween ) {
						anim.done( function() {
							style.display = restoreDisplay;
						} );
						if ( restoreDisplay == null ) {
							display = style.display;
							restoreDisplay = display === "none" ? "" : display;
						}
					}
					style.display = "inline-block";
				}
			}
		}
	
		if ( opts.overflow ) {
			style.overflow = "hidden";
			anim.always( function() {
				style.overflow = opts.overflow[ 0 ];
				style.overflowX = opts.overflow[ 1 ];
				style.overflowY = opts.overflow[ 2 ];
			} );
		}
	
		// Implement show/hide animations
		propTween = false;
		for ( prop in orig ) {
	
			// General show/hide setup for this element animation
			if ( !propTween ) {
				if ( dataShow ) {
					if ( "hidden" in dataShow ) {
						hidden = dataShow.hidden;
					}
				} else {
					dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
				}
	
				// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
				if ( toggle ) {
					dataShow.hidden = !hidden;
				}
	
				// Show elements before animating them
				if ( hidden ) {
					showHide( [ elem ], true );
				}
	
				/* eslint-disable no-loop-func */
	
				anim.done( function() {
	
				/* eslint-enable no-loop-func */
	
					// The final step of a "hide" animation is actually hiding the element
					if ( !hidden ) {
						showHide( [ elem ] );
					}
					dataPriv.remove( elem, "fxshow" );
					for ( prop in orig ) {
						jQuery.style( elem, prop, orig[ prop ] );
					}
				} );
			}
	
			// Per-property setup
			propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
			if ( !( prop in dataShow ) ) {
				dataShow[ prop ] = propTween.start;
				if ( hidden ) {
					propTween.end = propTween.start;
					propTween.start = 0;
				}
			}
		}
	}
	
	function propFilter( props, specialEasing ) {
		var index, name, easing, value, hooks;
	
		// camelCase, specialEasing and expand cssHook pass
		for ( index in props ) {
			name = jQuery.camelCase( index );
			easing = specialEasing[ name ];
			value = props[ index ];
			if ( Array.isArray( value ) ) {
				easing = value[ 1 ];
				value = props[ index ] = value[ 0 ];
			}
	
			if ( index !== name ) {
				props[ name ] = value;
				delete props[ index ];
			}
	
			hooks = jQuery.cssHooks[ name ];
			if ( hooks && "expand" in hooks ) {
				value = hooks.expand( value );
				delete props[ name ];
	
				// Not quite $.extend, this won't overwrite existing keys.
				// Reusing 'index' because we have the correct "name"
				for ( index in value ) {
					if ( !( index in props ) ) {
						props[ index ] = value[ index ];
						specialEasing[ index ] = easing;
					}
				}
			} else {
				specialEasing[ name ] = easing;
			}
		}
	}
	
	function Animation( elem, properties, options ) {
		var result,
			stopped,
			index = 0,
			length = Animation.prefilters.length,
			deferred = jQuery.Deferred().always( function() {
	
				// Don't match elem in the :animated selector
				delete tick.elem;
			} ),
			tick = function() {
				if ( stopped ) {
					return false;
				}
				var currentTime = fxNow || createFxNow(),
					remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
	
					// Support: Android 2.3 only
					// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
					temp = remaining / animation.duration || 0,
					percent = 1 - temp,
					index = 0,
					length = animation.tweens.length;
	
				for ( ; index < length; index++ ) {
					animation.tweens[ index ].run( percent );
				}
	
				deferred.notifyWith( elem, [ animation, percent, remaining ] );
	
				// If there's more to do, yield
				if ( percent < 1 && length ) {
					return remaining;
				}
	
				// If this was an empty animation, synthesize a final progress notification
				if ( !length ) {
					deferred.notifyWith( elem, [ animation, 1, 0 ] );
				}
	
				// Resolve the animation and report its conclusion
				deferred.resolveWith( elem, [ animation ] );
				return false;
			},
			animation = deferred.promise( {
				elem: elem,
				props: jQuery.extend( {}, properties ),
				opts: jQuery.extend( true, {
					specialEasing: {},
					easing: jQuery.easing._default
				}, options ),
				originalProperties: properties,
				originalOptions: options,
				startTime: fxNow || createFxNow(),
				duration: options.duration,
				tweens: [],
				createTween: function( prop, end ) {
					var tween = jQuery.Tween( elem, animation.opts, prop, end,
							animation.opts.specialEasing[ prop ] || animation.opts.easing );
					animation.tweens.push( tween );
					return tween;
				},
				stop: function( gotoEnd ) {
					var index = 0,
	
						// If we are going to the end, we want to run all the tweens
						// otherwise we skip this part
						length = gotoEnd ? animation.tweens.length : 0;
					if ( stopped ) {
						return this;
					}
					stopped = true;
					for ( ; index < length; index++ ) {
						animation.tweens[ index ].run( 1 );
					}
	
					// Resolve when we played the last frame; otherwise, reject
					if ( gotoEnd ) {
						deferred.notifyWith( elem, [ animation, 1, 0 ] );
						deferred.resolveWith( elem, [ animation, gotoEnd ] );
					} else {
						deferred.rejectWith( elem, [ animation, gotoEnd ] );
					}
					return this;
				}
			} ),
			props = animation.props;
	
		propFilter( props, animation.opts.specialEasing );
	
		for ( ; index < length; index++ ) {
			result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
			if ( result ) {
				if ( jQuery.isFunction( result.stop ) ) {
					jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
						jQuery.proxy( result.stop, result );
				}
				return result;
			}
		}
	
		jQuery.map( props, createTween, animation );
	
		if ( jQuery.isFunction( animation.opts.start ) ) {
			animation.opts.start.call( elem, animation );
		}
	
		// Attach callbacks from options
		animation
			.progress( animation.opts.progress )
			.done( animation.opts.done, animation.opts.complete )
			.fail( animation.opts.fail )
			.always( animation.opts.always );
	
		jQuery.fx.timer(
			jQuery.extend( tick, {
				elem: elem,
				anim: animation,
				queue: animation.opts.queue
			} )
		);
	
		return animation;
	}
	
	jQuery.Animation = jQuery.extend( Animation, {
	
		tweeners: {
			"*": [ function( prop, value ) {
				var tween = this.createTween( prop, value );
				adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
				return tween;
			} ]
		},
	
		tweener: function( props, callback ) {
			if ( jQuery.isFunction( props ) ) {
				callback = props;
				props = [ "*" ];
			} else {
				props = props.match( rnothtmlwhite );
			}
	
			var prop,
				index = 0,
				length = props.length;
	
			for ( ; index < length; index++ ) {
				prop = props[ index ];
				Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
				Animation.tweeners[ prop ].unshift( callback );
			}
		},
	
		prefilters: [ defaultPrefilter ],
	
		prefilter: function( callback, prepend ) {
			if ( prepend ) {
				Animation.prefilters.unshift( callback );
			} else {
				Animation.prefilters.push( callback );
			}
		}
	} );
	
	jQuery.speed = function( speed, easing, fn ) {
		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
			complete: fn || !fn && easing ||
				jQuery.isFunction( speed ) && speed,
			duration: speed,
			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
		};
	
		// Go to the end state if fx are off
		if ( jQuery.fx.off ) {
			opt.duration = 0;
	
		} else {
			if ( typeof opt.duration !== "number" ) {
				if ( opt.duration in jQuery.fx.speeds ) {
					opt.duration = jQuery.fx.speeds[ opt.duration ];
	
				} else {
					opt.duration = jQuery.fx.speeds._default;
				}
			}
		}
	
		// Normalize opt.queue - true/undefined/null -> "fx"
		if ( opt.queue == null || opt.queue === true ) {
			opt.queue = "fx";
		}
	
		// Queueing
		opt.old = opt.complete;
	
		opt.complete = function() {
			if ( jQuery.isFunction( opt.old ) ) {
				opt.old.call( this );
			}
	
			if ( opt.queue ) {
				jQuery.dequeue( this, opt.queue );
			}
		};
	
		return opt;
	};
	
	jQuery.fn.extend( {
		fadeTo: function( speed, to, easing, callback ) {
	
			// Show any hidden elements after setting opacity to 0
			return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
	
				// Animate to the value specified
				.end().animate( { opacity: to }, speed, easing, callback );
		},
		animate: function( prop, speed, easing, callback ) {
			var empty = jQuery.isEmptyObject( prop ),
				optall = jQuery.speed( speed, easing, callback ),
				doAnimation = function() {
	
					// Operate on a copy of prop so per-property easing won't be lost
					var anim = Animation( this, jQuery.extend( {}, prop ), optall );
	
					// Empty animations, or finishing resolves immediately
					if ( empty || dataPriv.get( this, "finish" ) ) {
						anim.stop( true );
					}
				};
				doAnimation.finish = doAnimation;
	
			return empty || optall.queue === false ?
				this.each( doAnimation ) :
				this.queue( optall.queue, doAnimation );
		},
		stop: function( type, clearQueue, gotoEnd ) {
			var stopQueue = function( hooks ) {
				var stop = hooks.stop;
				delete hooks.stop;
				stop( gotoEnd );
			};
	
			if ( typeof type !== "string" ) {
				gotoEnd = clearQueue;
				clearQueue = type;
				type = undefined;
			}
			if ( clearQueue && type !== false ) {
				this.queue( type || "fx", [] );
			}
	
			return this.each( function() {
				var dequeue = true,
					index = type != null && type + "queueHooks",
					timers = jQuery.timers,
					data = dataPriv.get( this );
	
				if ( index ) {
					if ( data[ index ] && data[ index ].stop ) {
						stopQueue( data[ index ] );
					}
				} else {
					for ( index in data ) {
						if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
							stopQueue( data[ index ] );
						}
					}
				}
	
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this &&
						( type == null || timers[ index ].queue === type ) ) {
	
						timers[ index ].anim.stop( gotoEnd );
						dequeue = false;
						timers.splice( index, 1 );
					}
				}
	
				// Start the next in the queue if the last step wasn't forced.
				// Timers currently will call their complete callbacks, which
				// will dequeue but only if they were gotoEnd.
				if ( dequeue || !gotoEnd ) {
					jQuery.dequeue( this, type );
				}
			} );
		},
		finish: function( type ) {
			if ( type !== false ) {
				type = type || "fx";
			}
			return this.each( function() {
				var index,
					data = dataPriv.get( this ),
					queue = data[ type + "queue" ],
					hooks = data[ type + "queueHooks" ],
					timers = jQuery.timers,
					length = queue ? queue.length : 0;
	
				// Enable finishing flag on private data
				data.finish = true;
	
				// Empty the queue first
				jQuery.queue( this, type, [] );
	
				if ( hooks && hooks.stop ) {
					hooks.stop.call( this, true );
				}
	
				// Look for any active animations, and finish them
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
						timers[ index ].anim.stop( true );
						timers.splice( index, 1 );
					}
				}
	
				// Look for any animations in the old queue and finish them
				for ( index = 0; index < length; index++ ) {
					if ( queue[ index ] && queue[ index ].finish ) {
						queue[ index ].finish.call( this );
					}
				}
	
				// Turn off finishing flag
				delete data.finish;
			} );
		}
	} );
	
	jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
		var cssFn = jQuery.fn[ name ];
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return speed == null || typeof speed === "boolean" ?
				cssFn.apply( this, arguments ) :
				this.animate( genFx( name, true ), speed, easing, callback );
		};
	} );
	
	// Generate shortcuts for custom animations
	jQuery.each( {
		slideDown: genFx( "show" ),
		slideUp: genFx( "hide" ),
		slideToggle: genFx( "toggle" ),
		fadeIn: { opacity: "show" },
		fadeOut: { opacity: "hide" },
		fadeToggle: { opacity: "toggle" }
	}, function( name, props ) {
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return this.animate( props, speed, easing, callback );
		};
	} );
	
	jQuery.timers = [];
	jQuery.fx.tick = function() {
		var timer,
			i = 0,
			timers = jQuery.timers;
	
		fxNow = jQuery.now();
	
		for ( ; i < timers.length; i++ ) {
			timer = timers[ i ];
	
			// Run the timer and safely remove it when done (allowing for external removal)
			if ( !timer() && timers[ i ] === timer ) {
				timers.splice( i--, 1 );
			}
		}
	
		if ( !timers.length ) {
			jQuery.fx.stop();
		}
		fxNow = undefined;
	};
	
	jQuery.fx.timer = function( timer ) {
		jQuery.timers.push( timer );
		jQuery.fx.start();
	};
	
	jQuery.fx.interval = 13;
	jQuery.fx.start = function() {
		if ( inProgress ) {
			return;
		}
	
		inProgress = true;
		schedule();
	};
	
	jQuery.fx.stop = function() {
		inProgress = null;
	};
	
	jQuery.fx.speeds = {
		slow: 600,
		fast: 200,
	
		// Default speed
		_default: 400
	};
	
	
	// Based off of the plugin by Clint Helfers, with permission.
	// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
	jQuery.fn.delay = function( time, type ) {
		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
		type = type || "fx";
	
		return this.queue( type, function( next, hooks ) {
			var timeout = window.setTimeout( next, time );
			hooks.stop = function() {
				window.clearTimeout( timeout );
			};
		} );
	};
	
	
	( function() {
		var input = document.createElement( "input" ),
			select = document.createElement( "select" ),
			opt = select.appendChild( document.createElement( "option" ) );
	
		input.type = "checkbox";
	
		// Support: Android <=4.3 only
		// Default value for a checkbox should be "on"
		support.checkOn = input.value !== "";
	
		// Support: IE <=11 only
		// Must access selectedIndex to make default options select
		support.optSelected = opt.selected;
	
		// Support: IE <=11 only
		// An input loses its value after becoming a radio
		input = document.createElement( "input" );
		input.value = "t";
		input.type = "radio";
		support.radioValue = input.value === "t";
	} )();
	
	
	var boolHook,
		attrHandle = jQuery.expr.attrHandle;
	
	jQuery.fn.extend( {
		attr: function( name, value ) {
			return access( this, jQuery.attr, name, value, arguments.length > 1 );
		},
	
		removeAttr: function( name ) {
			return this.each( function() {
				jQuery.removeAttr( this, name );
			} );
		}
	} );
	
	jQuery.extend( {
		attr: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set attributes on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			// Fallback to prop when attributes are not supported
			if ( typeof elem.getAttribute === "undefined" ) {
				return jQuery.prop( elem, name, value );
			}
	
			// Attribute hooks are determined by the lowercase version
			// Grab necessary hook if one is defined
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
				hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
					( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
			}
	
			if ( value !== undefined ) {
				if ( value === null ) {
					jQuery.removeAttr( elem, name );
					return;
				}
	
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				elem.setAttribute( name, value + "" );
				return value;
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			ret = jQuery.find.attr( elem, name );
	
			// Non-existent attributes return null, we normalize to undefined
			return ret == null ? undefined : ret;
		},
	
		attrHooks: {
			type: {
				set: function( elem, value ) {
					if ( !support.radioValue && value === "radio" &&
						nodeName( elem, "input" ) ) {
						var val = elem.value;
						elem.setAttribute( "type", value );
						if ( val ) {
							elem.value = val;
						}
						return value;
					}
				}
			}
		},
	
		removeAttr: function( elem, value ) {
			var name,
				i = 0,
	
				// Attribute names can contain non-HTML whitespace characters
				// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
				attrNames = value && value.match( rnothtmlwhite );
	
			if ( attrNames && elem.nodeType === 1 ) {
				while ( ( name = attrNames[ i++ ] ) ) {
					elem.removeAttribute( name );
				}
			}
		}
	} );
	
	// Hooks for boolean attributes
	boolHook = {
		set: function( elem, value, name ) {
			if ( value === false ) {
	
				// Remove boolean attributes when set to false
				jQuery.removeAttr( elem, name );
			} else {
				elem.setAttribute( name, name );
			}
			return name;
		}
	};
	
	jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
		var getter = attrHandle[ name ] || jQuery.find.attr;
	
		attrHandle[ name ] = function( elem, name, isXML ) {
			var ret, handle,
				lowercaseName = name.toLowerCase();
	
			if ( !isXML ) {
	
				// Avoid an infinite loop by temporarily removing this function from the getter
				handle = attrHandle[ lowercaseName ];
				attrHandle[ lowercaseName ] = ret;
				ret = getter( elem, name, isXML ) != null ?
					lowercaseName :
					null;
				attrHandle[ lowercaseName ] = handle;
			}
			return ret;
		};
	} );
	
	
	
	
	var rfocusable = /^(?:input|select|textarea|button)$/i,
		rclickable = /^(?:a|area)$/i;
	
	jQuery.fn.extend( {
		prop: function( name, value ) {
			return access( this, jQuery.prop, name, value, arguments.length > 1 );
		},
	
		removeProp: function( name ) {
			return this.each( function() {
				delete this[ jQuery.propFix[ name ] || name ];
			} );
		}
	} );
	
	jQuery.extend( {
		prop: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set properties on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
	
				// Fix name and attach hooks
				name = jQuery.propFix[ name ] || name;
				hooks = jQuery.propHooks[ name ];
			}
	
			if ( value !== undefined ) {
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				return ( elem[ name ] = value );
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			return elem[ name ];
		},
	
		propHooks: {
			tabIndex: {
				get: function( elem ) {
	
					// Support: IE <=9 - 11 only
					// elem.tabIndex doesn't always return the
					// correct value when it hasn't been explicitly set
					// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
					// Use proper attribute retrieval(#12072)
					var tabindex = jQuery.find.attr( elem, "tabindex" );
	
					if ( tabindex ) {
						return parseInt( tabindex, 10 );
					}
	
					if (
						rfocusable.test( elem.nodeName ) ||
						rclickable.test( elem.nodeName ) &&
						elem.href
					) {
						return 0;
					}
	
					return -1;
				}
			}
		},
	
		propFix: {
			"for": "htmlFor",
			"class": "className"
		}
	} );
	
	// Support: IE <=11 only
	// Accessing the selectedIndex property
	// forces the browser to respect setting selected
	// on the option
	// The getter ensures a default option is selected
	// when in an optgroup
	// eslint rule "no-unused-expressions" is disabled for this code
	// since it considers such accessions noop
	if ( !support.optSelected ) {
		jQuery.propHooks.selected = {
			get: function( elem ) {
	
				/* eslint no-unused-expressions: "off" */
	
				var parent = elem.parentNode;
				if ( parent && parent.parentNode ) {
					parent.parentNode.selectedIndex;
				}
				return null;
			},
			set: function( elem ) {
	
				/* eslint no-unused-expressions: "off" */
	
				var parent = elem.parentNode;
				if ( parent ) {
					parent.selectedIndex;
	
					if ( parent.parentNode ) {
						parent.parentNode.selectedIndex;
					}
				}
			}
		};
	}
	
	jQuery.each( [
		"tabIndex",
		"readOnly",
		"maxLength",
		"cellSpacing",
		"cellPadding",
		"rowSpan",
		"colSpan",
		"useMap",
		"frameBorder",
		"contentEditable"
	], function() {
		jQuery.propFix[ this.toLowerCase() ] = this;
	} );
	
	
	
	
		// Strip and collapse whitespace according to HTML spec
		// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
		function stripAndCollapse( value ) {
			var tokens = value.match( rnothtmlwhite ) || [];
			return tokens.join( " " );
		}
	
	
	function getClass( elem ) {
		return elem.getAttribute && elem.getAttribute( "class" ) || "";
	}
	
	jQuery.fn.extend( {
		addClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnothtmlwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
					cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
							if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
								cur += clazz + " ";
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = stripAndCollapse( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		removeClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( !arguments.length ) {
				return this.attr( "class", "" );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnothtmlwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
	
					// This expression is here for better compressibility (see addClass)
					cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
	
							// Remove *all* instances
							while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
								cur = cur.replace( " " + clazz + " ", " " );
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = stripAndCollapse( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		toggleClass: function( value, stateVal ) {
			var type = typeof value;
	
			if ( typeof stateVal === "boolean" && type === "string" ) {
				return stateVal ? this.addClass( value ) : this.removeClass( value );
			}
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( i ) {
					jQuery( this ).toggleClass(
						value.call( this, i, getClass( this ), stateVal ),
						stateVal
					);
				} );
			}
	
			return this.each( function() {
				var className, i, self, classNames;
	
				if ( type === "string" ) {
	
					// Toggle individual class names
					i = 0;
					self = jQuery( this );
					classNames = value.match( rnothtmlwhite ) || [];
	
					while ( ( className = classNames[ i++ ] ) ) {
	
						// Check each className given, space separated list
						if ( self.hasClass( className ) ) {
							self.removeClass( className );
						} else {
							self.addClass( className );
						}
					}
	
				// Toggle whole class name
				} else if ( value === undefined || type === "boolean" ) {
					className = getClass( this );
					if ( className ) {
	
						// Store className if set
						dataPriv.set( this, "__className__", className );
					}
	
					// If the element has a class name or if we're passed `false`,
					// then remove the whole classname (if there was one, the above saved it).
					// Otherwise bring back whatever was previously saved (if anything),
					// falling back to the empty string if nothing was stored.
					if ( this.setAttribute ) {
						this.setAttribute( "class",
							className || value === false ?
							"" :
							dataPriv.get( this, "__className__" ) || ""
						);
					}
				}
			} );
		},
	
		hasClass: function( selector ) {
			var className, elem,
				i = 0;
	
			className = " " + selector + " ";
			while ( ( elem = this[ i++ ] ) ) {
				if ( elem.nodeType === 1 &&
					( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
						return true;
				}
			}
	
			return false;
		}
	} );
	
	
	
	
	var rreturn = /\r/g;
	
	jQuery.fn.extend( {
		val: function( value ) {
			var hooks, ret, isFunction,
				elem = this[ 0 ];
	
			if ( !arguments.length ) {
				if ( elem ) {
					hooks = jQuery.valHooks[ elem.type ] ||
						jQuery.valHooks[ elem.nodeName.toLowerCase() ];
	
					if ( hooks &&
						"get" in hooks &&
						( ret = hooks.get( elem, "value" ) ) !== undefined
					) {
						return ret;
					}
	
					ret = elem.value;
	
					// Handle most common string cases
					if ( typeof ret === "string" ) {
						return ret.replace( rreturn, "" );
					}
	
					// Handle cases where value is null/undef or number
					return ret == null ? "" : ret;
				}
	
				return;
			}
	
			isFunction = jQuery.isFunction( value );
	
			return this.each( function( i ) {
				var val;
	
				if ( this.nodeType !== 1 ) {
					return;
				}
	
				if ( isFunction ) {
					val = value.call( this, i, jQuery( this ).val() );
				} else {
					val = value;
				}
	
				// Treat null/undefined as ""; convert numbers to string
				if ( val == null ) {
					val = "";
	
				} else if ( typeof val === "number" ) {
					val += "";
	
				} else if ( Array.isArray( val ) ) {
					val = jQuery.map( val, function( value ) {
						return value == null ? "" : value + "";
					} );
				}
	
				hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
	
				// If set returns undefined, fall back to normal setting
				if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
					this.value = val;
				}
			} );
		}
	} );
	
	jQuery.extend( {
		valHooks: {
			option: {
				get: function( elem ) {
	
					var val = jQuery.find.attr( elem, "value" );
					return val != null ?
						val :
	
						// Support: IE <=10 - 11 only
						// option.text throws exceptions (#14686, #14858)
						// Strip and collapse whitespace
						// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
						stripAndCollapse( jQuery.text( elem ) );
				}
			},
			select: {
				get: function( elem ) {
					var value, option, i,
						options = elem.options,
						index = elem.selectedIndex,
						one = elem.type === "select-one",
						values = one ? null : [],
						max = one ? index + 1 : options.length;
	
					if ( index < 0 ) {
						i = max;
	
					} else {
						i = one ? index : 0;
					}
	
					// Loop through all the selected options
					for ( ; i < max; i++ ) {
						option = options[ i ];
	
						// Support: IE <=9 only
						// IE8-9 doesn't update selected after form reset (#2551)
						if ( ( option.selected || i === index ) &&
	
								// Don't return options that are disabled or in a disabled optgroup
								!option.disabled &&
								( !option.parentNode.disabled ||
									!nodeName( option.parentNode, "optgroup" ) ) ) {
	
							// Get the specific value for the option
							value = jQuery( option ).val();
	
							// We don't need an array for one selects
							if ( one ) {
								return value;
							}
	
							// Multi-Selects return an array
							values.push( value );
						}
					}
	
					return values;
				},
	
				set: function( elem, value ) {
					var optionSet, option,
						options = elem.options,
						values = jQuery.makeArray( value ),
						i = options.length;
	
					while ( i-- ) {
						option = options[ i ];
	
						/* eslint-disable no-cond-assign */
	
						if ( option.selected =
							jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
						) {
							optionSet = true;
						}
	
						/* eslint-enable no-cond-assign */
					}
	
					// Force browsers to behave consistently when non-matching value is set
					if ( !optionSet ) {
						elem.selectedIndex = -1;
					}
					return values;
				}
			}
		}
	} );
	
	// Radios and checkboxes getter/setter
	jQuery.each( [ "radio", "checkbox" ], function() {
		jQuery.valHooks[ this ] = {
			set: function( elem, value ) {
				if ( Array.isArray( value ) ) {
					return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
				}
			}
		};
		if ( !support.checkOn ) {
			jQuery.valHooks[ this ].get = function( elem ) {
				return elem.getAttribute( "value" ) === null ? "on" : elem.value;
			};
		}
	} );
	
	
	
	
	// Return jQuery for attributes-only inclusion
	
	
	var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
	
	jQuery.extend( jQuery.event, {
	
		trigger: function( event, data, elem, onlyHandlers ) {
	
			var i, cur, tmp, bubbleType, ontype, handle, special,
				eventPath = [ elem || document ],
				type = hasOwn.call( event, "type" ) ? event.type : event,
				namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
	
			cur = tmp = elem = elem || document;
	
			// Don't do events on text and comment nodes
			if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
				return;
			}
	
			// focus/blur morphs to focusin/out; ensure we're not firing them right now
			if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
				return;
			}
	
			if ( type.indexOf( "." ) > -1 ) {
	
				// Namespaced trigger; create a regexp to match event type in handle()
				namespaces = type.split( "." );
				type = namespaces.shift();
				namespaces.sort();
			}
			ontype = type.indexOf( ":" ) < 0 && "on" + type;
	
			// Caller can pass in a jQuery.Event object, Object, or just an event type string
			event = event[ jQuery.expando ] ?
				event :
				new jQuery.Event( type, typeof event === "object" && event );
	
			// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
			event.isTrigger = onlyHandlers ? 2 : 3;
			event.namespace = namespaces.join( "." );
			event.rnamespace = event.namespace ?
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
				null;
	
			// Clean up the event in case it is being reused
			event.result = undefined;
			if ( !event.target ) {
				event.target = elem;
			}
	
			// Clone any incoming data and prepend the event, creating the handler arg list
			data = data == null ?
				[ event ] :
				jQuery.makeArray( data, [ event ] );
	
			// Allow special events to draw outside the lines
			special = jQuery.event.special[ type ] || {};
			if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
				return;
			}
	
			// Determine event propagation path in advance, per W3C events spec (#9951)
			// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
			if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
	
				bubbleType = special.delegateType || type;
				if ( !rfocusMorph.test( bubbleType + type ) ) {
					cur = cur.parentNode;
				}
				for ( ; cur; cur = cur.parentNode ) {
					eventPath.push( cur );
					tmp = cur;
				}
	
				// Only add window if we got to document (e.g., not plain obj or detached DOM)
				if ( tmp === ( elem.ownerDocument || document ) ) {
					eventPath.push( tmp.defaultView || tmp.parentWindow || window );
				}
			}
	
			// Fire handlers on the event path
			i = 0;
			while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
	
				event.type = i > 1 ?
					bubbleType :
					special.bindType || type;
	
				// jQuery handler
				handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
					dataPriv.get( cur, "handle" );
				if ( handle ) {
					handle.apply( cur, data );
				}
	
				// Native handler
				handle = ontype && cur[ ontype ];
				if ( handle && handle.apply && acceptData( cur ) ) {
					event.result = handle.apply( cur, data );
					if ( event.result === false ) {
						event.preventDefault();
					}
				}
			}
			event.type = type;
	
			// If nobody prevented the default action, do it now
			if ( !onlyHandlers && !event.isDefaultPrevented() ) {
	
				if ( ( !special._default ||
					special._default.apply( eventPath.pop(), data ) === false ) &&
					acceptData( elem ) ) {
	
					// Call a native DOM method on the target with the same name as the event.
					// Don't do default actions on window, that's where global variables be (#6170)
					if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
	
						// Don't re-trigger an onFOO event when we call its FOO() method
						tmp = elem[ ontype ];
	
						if ( tmp ) {
							elem[ ontype ] = null;
						}
	
						// Prevent re-triggering of the same event, since we already bubbled it above
						jQuery.event.triggered = type;
						elem[ type ]();
						jQuery.event.triggered = undefined;
	
						if ( tmp ) {
							elem[ ontype ] = tmp;
						}
					}
				}
			}
	
			return event.result;
		},
	
		// Piggyback on a donor event to simulate a different one
		// Used only for `focus(in | out)` events
		simulate: function( type, elem, event ) {
			var e = jQuery.extend(
				new jQuery.Event(),
				event,
				{
					type: type,
					isSimulated: true
				}
			);
	
			jQuery.event.trigger( e, null, elem );
		}
	
	} );
	
	jQuery.fn.extend( {
	
		trigger: function( type, data ) {
			return this.each( function() {
				jQuery.event.trigger( type, data, this );
			} );
		},
		triggerHandler: function( type, data ) {
			var elem = this[ 0 ];
			if ( elem ) {
				return jQuery.event.trigger( type, data, elem, true );
			}
		}
	} );
	
	
	jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
		"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
		"change select submit keydown keypress keyup contextmenu" ).split( " " ),
		function( i, name ) {
	
		// Handle event binding
		jQuery.fn[ name ] = function( data, fn ) {
			return arguments.length > 0 ?
				this.on( name, null, data, fn ) :
				this.trigger( name );
		};
	} );
	
	jQuery.fn.extend( {
		hover: function( fnOver, fnOut ) {
			return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
		}
	} );
	
	
	
	
	support.focusin = "onfocusin" in window;
	
	
	// Support: Firefox <=44
	// Firefox doesn't have focus(in | out) events
	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
	//
	// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
	// focus(in | out) events fire after focus & blur events,
	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
	// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
	if ( !support.focusin ) {
		jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
	
			// Attach a single capturing handler on the document while someone wants focusin/focusout
			var handler = function( event ) {
				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
			};
	
			jQuery.event.special[ fix ] = {
				setup: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix );
	
					if ( !attaches ) {
						doc.addEventListener( orig, handler, true );
					}
					dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
				},
				teardown: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix ) - 1;
	
					if ( !attaches ) {
						doc.removeEventListener( orig, handler, true );
						dataPriv.remove( doc, fix );
	
					} else {
						dataPriv.access( doc, fix, attaches );
					}
				}
			};
		} );
	}
	var location = window.location;
	
	var nonce = jQuery.now();
	
	var rquery = ( /\?/ );
	
	
	
	// Cross-browser xml parsing
	jQuery.parseXML = function( data ) {
		var xml;
		if ( !data || typeof data !== "string" ) {
			return null;
		}
	
		// Support: IE 9 - 11 only
		// IE throws on parseFromString with invalid input.
		try {
			xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
		} catch ( e ) {
			xml = undefined;
		}
	
		if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
			jQuery.error( "Invalid XML: " + data );
		}
		return xml;
	};
	
	
	var
		rbracket = /\[\]$/,
		rCRLF = /\r?\n/g,
		rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
		rsubmittable = /^(?:input|select|textarea|keygen)/i;
	
	function buildParams( prefix, obj, traditional, add ) {
		var name;
	
		if ( Array.isArray( obj ) ) {
	
			// Serialize array item.
			jQuery.each( obj, function( i, v ) {
				if ( traditional || rbracket.test( prefix ) ) {
	
					// Treat each array item as a scalar.
					add( prefix, v );
	
				} else {
	
					// Item is non-scalar (array or object), encode its numeric index.
					buildParams(
						prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
						v,
						traditional,
						add
					);
				}
			} );
	
		} else if ( !traditional && jQuery.type( obj ) === "object" ) {
	
			// Serialize object item.
			for ( name in obj ) {
				buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
			}
	
		} else {
	
			// Serialize scalar item.
			add( prefix, obj );
		}
	}
	
	// Serialize an array of form elements or a set of
	// key/values into a query string
	jQuery.param = function( a, traditional ) {
		var prefix,
			s = [],
			add = function( key, valueOrFunction ) {
	
				// If value is a function, invoke it and use its return value
				var value = jQuery.isFunction( valueOrFunction ) ?
					valueOrFunction() :
					valueOrFunction;
	
				s[ s.length ] = encodeURIComponent( key ) + "=" +
					encodeURIComponent( value == null ? "" : value );
			};
	
		// If an array was passed in, assume that it is an array of form elements.
		if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
	
			// Serialize the form elements
			jQuery.each( a, function() {
				add( this.name, this.value );
			} );
	
		} else {
	
			// If traditional, encode the "old" way (the way 1.3.2 or older
			// did it), otherwise encode params recursively.
			for ( prefix in a ) {
				buildParams( prefix, a[ prefix ], traditional, add );
			}
		}
	
		// Return the resulting serialization
		return s.join( "&" );
	};
	
	jQuery.fn.extend( {
		serialize: function() {
			return jQuery.param( this.serializeArray() );
		},
		serializeArray: function() {
			return this.map( function() {
	
				// Can add propHook for "elements" to filter or add form elements
				var elements = jQuery.prop( this, "elements" );
				return elements ? jQuery.makeArray( elements ) : this;
			} )
			.filter( function() {
				var type = this.type;
	
				// Use .is( ":disabled" ) so that fieldset[disabled] works
				return this.name && !jQuery( this ).is( ":disabled" ) &&
					rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
					( this.checked || !rcheckableType.test( type ) );
			} )
			.map( function( i, elem ) {
				var val = jQuery( this ).val();
	
				if ( val == null ) {
					return null;
				}
	
				if ( Array.isArray( val ) ) {
					return jQuery.map( val, function( val ) {
						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
					} );
				}
	
				return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
			} ).get();
		}
	} );
	
	
	var
		r20 = /%20/g,
		rhash = /#.*$/,
		rantiCache = /([?&])_=[^&]*/,
		rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
	
		// #7653, #8125, #8152: local protocol detection
		rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
		rnoContent = /^(?:GET|HEAD)$/,
		rprotocol = /^\/\//,
	
		/* Prefilters
		 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
		 * 2) These are called:
		 *    - BEFORE asking for a transport
		 *    - AFTER param serialization (s.data is a string if s.processData is true)
		 * 3) key is the dataType
		 * 4) the catchall symbol "*" can be used
		 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
		 */
		prefilters = {},
	
		/* Transports bindings
		 * 1) key is the dataType
		 * 2) the catchall symbol "*" can be used
		 * 3) selection will start with transport dataType and THEN go to "*" if needed
		 */
		transports = {},
	
		// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
		allTypes = "*/".concat( "*" ),
	
		// Anchor tag for parsing the document origin
		originAnchor = document.createElement( "a" );
		originAnchor.href = location.href;
	
	// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
	function addToPrefiltersOrTransports( structure ) {
	
		// dataTypeExpression is optional and defaults to "*"
		return function( dataTypeExpression, func ) {
	
			if ( typeof dataTypeExpression !== "string" ) {
				func = dataTypeExpression;
				dataTypeExpression = "*";
			}
	
			var dataType,
				i = 0,
				dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
	
			if ( jQuery.isFunction( func ) ) {
	
				// For each dataType in the dataTypeExpression
				while ( ( dataType = dataTypes[ i++ ] ) ) {
	
					// Prepend if requested
					if ( dataType[ 0 ] === "+" ) {
						dataType = dataType.slice( 1 ) || "*";
						( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
	
					// Otherwise append
					} else {
						( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
					}
				}
			}
		};
	}
	
	// Base inspection function for prefilters and transports
	function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
	
		var inspected = {},
			seekingTransport = ( structure === transports );
	
		function inspect( dataType ) {
			var selected;
			inspected[ dataType ] = true;
			jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
				var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
				if ( typeof dataTypeOrTransport === "string" &&
					!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
	
					options.dataTypes.unshift( dataTypeOrTransport );
					inspect( dataTypeOrTransport );
					return false;
				} else if ( seekingTransport ) {
					return !( selected = dataTypeOrTransport );
				}
			} );
			return selected;
		}
	
		return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
	}
	
	// A special extend for ajax options
	// that takes "flat" options (not to be deep extended)
	// Fixes #9887
	function ajaxExtend( target, src ) {
		var key, deep,
			flatOptions = jQuery.ajaxSettings.flatOptions || {};
	
		for ( key in src ) {
			if ( src[ key ] !== undefined ) {
				( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
			}
		}
		if ( deep ) {
			jQuery.extend( true, target, deep );
		}
	
		return target;
	}
	
	/* Handles responses to an ajax request:
	 * - finds the right dataType (mediates between content-type and expected dataType)
	 * - returns the corresponding response
	 */
	function ajaxHandleResponses( s, jqXHR, responses ) {
	
		var ct, type, finalDataType, firstDataType,
			contents = s.contents,
			dataTypes = s.dataTypes;
	
		// Remove auto dataType and get content-type in the process
		while ( dataTypes[ 0 ] === "*" ) {
			dataTypes.shift();
			if ( ct === undefined ) {
				ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
			}
		}
	
		// Check if we're dealing with a known content-type
		if ( ct ) {
			for ( type in contents ) {
				if ( contents[ type ] && contents[ type ].test( ct ) ) {
					dataTypes.unshift( type );
					break;
				}
			}
		}
	
		// Check to see if we have a response for the expected dataType
		if ( dataTypes[ 0 ] in responses ) {
			finalDataType = dataTypes[ 0 ];
		} else {
	
			// Try convertible dataTypes
			for ( type in responses ) {
				if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
					finalDataType = type;
					break;
				}
				if ( !firstDataType ) {
					firstDataType = type;
				}
			}
	
			// Or just use first one
			finalDataType = finalDataType || firstDataType;
		}
	
		// If we found a dataType
		// We add the dataType to the list if needed
		// and return the corresponding response
		if ( finalDataType ) {
			if ( finalDataType !== dataTypes[ 0 ] ) {
				dataTypes.unshift( finalDataType );
			}
			return responses[ finalDataType ];
		}
	}
	
	/* Chain conversions given the request and the original response
	 * Also sets the responseXXX fields on the jqXHR instance
	 */
	function ajaxConvert( s, response, jqXHR, isSuccess ) {
		var conv2, current, conv, tmp, prev,
			converters = {},
	
			// Work with a copy of dataTypes in case we need to modify it for conversion
			dataTypes = s.dataTypes.slice();
	
		// Create converters map with lowercased keys
		if ( dataTypes[ 1 ] ) {
			for ( conv in s.converters ) {
				converters[ conv.toLowerCase() ] = s.converters[ conv ];
			}
		}
	
		current = dataTypes.shift();
	
		// Convert to each sequential dataType
		while ( current ) {
	
			if ( s.responseFields[ current ] ) {
				jqXHR[ s.responseFields[ current ] ] = response;
			}
	
			// Apply the dataFilter if provided
			if ( !prev && isSuccess && s.dataFilter ) {
				response = s.dataFilter( response, s.dataType );
			}
	
			prev = current;
			current = dataTypes.shift();
	
			if ( current ) {
	
				// There's only work to do if current dataType is non-auto
				if ( current === "*" ) {
	
					current = prev;
	
				// Convert response if prev dataType is non-auto and differs from current
				} else if ( prev !== "*" && prev !== current ) {
	
					// Seek a direct converter
					conv = converters[ prev + " " + current ] || converters[ "* " + current ];
	
					// If none found, seek a pair
					if ( !conv ) {
						for ( conv2 in converters ) {
	
							// If conv2 outputs current
							tmp = conv2.split( " " );
							if ( tmp[ 1 ] === current ) {
	
								// If prev can be converted to accepted input
								conv = converters[ prev + " " + tmp[ 0 ] ] ||
									converters[ "* " + tmp[ 0 ] ];
								if ( conv ) {
	
									// Condense equivalence converters
									if ( conv === true ) {
										conv = converters[ conv2 ];
	
									// Otherwise, insert the intermediate dataType
									} else if ( converters[ conv2 ] !== true ) {
										current = tmp[ 0 ];
										dataTypes.unshift( tmp[ 1 ] );
									}
									break;
								}
							}
						}
					}
	
					// Apply converter (if not an equivalence)
					if ( conv !== true ) {
	
						// Unless errors are allowed to bubble, catch and return them
						if ( conv && s.throws ) {
							response = conv( response );
						} else {
							try {
								response = conv( response );
							} catch ( e ) {
								return {
									state: "parsererror",
									error: conv ? e : "No conversion from " + prev + " to " + current
								};
							}
						}
					}
				}
			}
		}
	
		return { state: "success", data: response };
	}
	
	jQuery.extend( {
	
		// Counter for holding the number of active queries
		active: 0,
	
		// Last-Modified header cache for next request
		lastModified: {},
		etag: {},
	
		ajaxSettings: {
			url: location.href,
			type: "GET",
			isLocal: rlocalProtocol.test( location.protocol ),
			global: true,
			processData: true,
			async: true,
			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
	
			/*
			timeout: 0,
			data: null,
			dataType: null,
			username: null,
			password: null,
			cache: null,
			throws: false,
			traditional: false,
			headers: {},
			*/
	
			accepts: {
				"*": allTypes,
				text: "text/plain",
				html: "text/html",
				xml: "application/xml, text/xml",
				json: "application/json, text/javascript"
			},
	
			contents: {
				xml: /\bxml\b/,
				html: /\bhtml/,
				json: /\bjson\b/
			},
	
			responseFields: {
				xml: "responseXML",
				text: "responseText",
				json: "responseJSON"
			},
	
			// Data converters
			// Keys separate source (or catchall "*") and destination types with a single space
			converters: {
	
				// Convert anything to text
				"* text": String,
	
				// Text to html (true = no transformation)
				"text html": true,
	
				// Evaluate text as a json expression
				"text json": JSON.parse,
	
				// Parse text as xml
				"text xml": jQuery.parseXML
			},
	
			// For options that shouldn't be deep extended:
			// you can add your own custom options here if
			// and when you create one that shouldn't be
			// deep extended (see ajaxExtend)
			flatOptions: {
				url: true,
				context: true
			}
		},
	
		// Creates a full fledged settings object into target
		// with both ajaxSettings and settings fields.
		// If target is omitted, writes into ajaxSettings.
		ajaxSetup: function( target, settings ) {
			return settings ?
	
				// Building a settings object
				ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
	
				// Extending ajaxSettings
				ajaxExtend( jQuery.ajaxSettings, target );
		},
	
		ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
		ajaxTransport: addToPrefiltersOrTransports( transports ),
	
		// Main method
		ajax: function( url, options ) {
	
			// If url is an object, simulate pre-1.5 signature
			if ( typeof url === "object" ) {
				options = url;
				url = undefined;
			}
	
			// Force options to be an object
			options = options || {};
	
			var transport,
	
				// URL without anti-cache param
				cacheURL,
	
				// Response headers
				responseHeadersString,
				responseHeaders,
	
				// timeout handle
				timeoutTimer,
	
				// Url cleanup var
				urlAnchor,
	
				// Request state (becomes false upon send and true upon completion)
				completed,
	
				// To know if global events are to be dispatched
				fireGlobals,
	
				// Loop variable
				i,
	
				// uncached part of the url
				uncached,
	
				// Create the final options object
				s = jQuery.ajaxSetup( {}, options ),
	
				// Callbacks context
				callbackContext = s.context || s,
	
				// Context for global events is callbackContext if it is a DOM node or jQuery collection
				globalEventContext = s.context &&
					( callbackContext.nodeType || callbackContext.jquery ) ?
						jQuery( callbackContext ) :
						jQuery.event,
	
				// Deferreds
				deferred = jQuery.Deferred(),
				completeDeferred = jQuery.Callbacks( "once memory" ),
	
				// Status-dependent callbacks
				statusCode = s.statusCode || {},
	
				// Headers (they are sent all at once)
				requestHeaders = {},
				requestHeadersNames = {},
	
				// Default abort message
				strAbort = "canceled",
	
				// Fake xhr
				jqXHR = {
					readyState: 0,
	
					// Builds headers hashtable if needed
					getResponseHeader: function( key ) {
						var match;
						if ( completed ) {
							if ( !responseHeaders ) {
								responseHeaders = {};
								while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
									responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
								}
							}
							match = responseHeaders[ key.toLowerCase() ];
						}
						return match == null ? null : match;
					},
	
					// Raw string
					getAllResponseHeaders: function() {
						return completed ? responseHeadersString : null;
					},
	
					// Caches the header
					setRequestHeader: function( name, value ) {
						if ( completed == null ) {
							name = requestHeadersNames[ name.toLowerCase() ] =
								requestHeadersNames[ name.toLowerCase() ] || name;
							requestHeaders[ name ] = value;
						}
						return this;
					},
	
					// Overrides response content-type header
					overrideMimeType: function( type ) {
						if ( completed == null ) {
							s.mimeType = type;
						}
						return this;
					},
	
					// Status-dependent callbacks
					statusCode: function( map ) {
						var code;
						if ( map ) {
							if ( completed ) {
	
								// Execute the appropriate callbacks
								jqXHR.always( map[ jqXHR.status ] );
							} else {
	
								// Lazy-add the new callbacks in a way that preserves old ones
								for ( code in map ) {
									statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
								}
							}
						}
						return this;
					},
	
					// Cancel the request
					abort: function( statusText ) {
						var finalText = statusText || strAbort;
						if ( transport ) {
							transport.abort( finalText );
						}
						done( 0, finalText );
						return this;
					}
				};
	
			// Attach deferreds
			deferred.promise( jqXHR );
	
			// Add protocol if not provided (prefilters might expect it)
			// Handle falsy url in the settings object (#10093: consistency with old signature)
			// We also use the url parameter if available
			s.url = ( ( url || s.url || location.href ) + "" )
				.replace( rprotocol, location.protocol + "//" );
	
			// Alias method option to type as per ticket #12004
			s.type = options.method || options.type || s.method || s.type;
	
			// Extract dataTypes list
			s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
	
			// A cross-domain request is in order when the origin doesn't match the current origin.
			if ( s.crossDomain == null ) {
				urlAnchor = document.createElement( "a" );
	
				// Support: IE <=8 - 11, Edge 12 - 13
				// IE throws exception on accessing the href property if url is malformed,
				// e.g. http://example.com:80x/
				try {
					urlAnchor.href = s.url;
	
					// Support: IE <=8 - 11 only
					// Anchor's host property isn't correctly set when s.url is relative
					urlAnchor.href = urlAnchor.href;
					s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
						urlAnchor.protocol + "//" + urlAnchor.host;
				} catch ( e ) {
	
					// If there is an error parsing the URL, assume it is crossDomain,
					// it can be rejected by the transport if it is invalid
					s.crossDomain = true;
				}
			}
	
			// Convert data if not already a string
			if ( s.data && s.processData && typeof s.data !== "string" ) {
				s.data = jQuery.param( s.data, s.traditional );
			}
	
			// Apply prefilters
			inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
	
			// If request was aborted inside a prefilter, stop there
			if ( completed ) {
				return jqXHR;
			}
	
			// We can fire global events as of now if asked to
			// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
			fireGlobals = jQuery.event && s.global;
	
			// Watch for a new set of requests
			if ( fireGlobals && jQuery.active++ === 0 ) {
				jQuery.event.trigger( "ajaxStart" );
			}
	
			// Uppercase the type
			s.type = s.type.toUpperCase();
	
			// Determine if request has content
			s.hasContent = !rnoContent.test( s.type );
	
			// Save the URL in case we're toying with the If-Modified-Since
			// and/or If-None-Match header later on
			// Remove hash to simplify url manipulation
			cacheURL = s.url.replace( rhash, "" );
	
			// More options handling for requests with no content
			if ( !s.hasContent ) {
	
				// Remember the hash so we can put it back
				uncached = s.url.slice( cacheURL.length );
	
				// If data is available, append data to url
				if ( s.data ) {
					cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
	
					// #9682: remove data so that it's not used in an eventual retry
					delete s.data;
				}
	
				// Add or update anti-cache param if needed
				if ( s.cache === false ) {
					cacheURL = cacheURL.replace( rantiCache, "$1" );
					uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
				}
	
				// Put hash and anti-cache on the URL that will be requested (gh-1732)
				s.url = cacheURL + uncached;
	
			// Change '%20' to '+' if this is encoded form body content (gh-2658)
			} else if ( s.data && s.processData &&
				( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
				s.data = s.data.replace( r20, "+" );
			}
	
			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
			if ( s.ifModified ) {
				if ( jQuery.lastModified[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
				}
				if ( jQuery.etag[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
				}
			}
	
			// Set the correct header, if data is being sent
			if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
				jqXHR.setRequestHeader( "Content-Type", s.contentType );
			}
	
			// Set the Accepts header for the server, depending on the dataType
			jqXHR.setRequestHeader(
				"Accept",
				s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
					s.accepts[ s.dataTypes[ 0 ] ] +
						( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
					s.accepts[ "*" ]
			);
	
			// Check for headers option
			for ( i in s.headers ) {
				jqXHR.setRequestHeader( i, s.headers[ i ] );
			}
	
			// Allow custom headers/mimetypes and early abort
			if ( s.beforeSend &&
				( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
	
				// Abort if not done already and return
				return jqXHR.abort();
			}
	
			// Aborting is no longer a cancellation
			strAbort = "abort";
	
			// Install callbacks on deferreds
			completeDeferred.add( s.complete );
			jqXHR.done( s.success );
			jqXHR.fail( s.error );
	
			// Get transport
			transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
	
			// If no transport, we auto-abort
			if ( !transport ) {
				done( -1, "No Transport" );
			} else {
				jqXHR.readyState = 1;
	
				// Send global event
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
				}
	
				// If request was aborted inside ajaxSend, stop there
				if ( completed ) {
					return jqXHR;
				}
	
				// Timeout
				if ( s.async && s.timeout > 0 ) {
					timeoutTimer = window.setTimeout( function() {
						jqXHR.abort( "timeout" );
					}, s.timeout );
				}
	
				try {
					completed = false;
					transport.send( requestHeaders, done );
				} catch ( e ) {
	
					// Rethrow post-completion exceptions
					if ( completed ) {
						throw e;
					}
	
					// Propagate others as results
					done( -1, e );
				}
			}
	
			// Callback for when everything is done
			function done( status, nativeStatusText, responses, headers ) {
				var isSuccess, success, error, response, modified,
					statusText = nativeStatusText;
	
				// Ignore repeat invocations
				if ( completed ) {
					return;
				}
	
				completed = true;
	
				// Clear timeout if it exists
				if ( timeoutTimer ) {
					window.clearTimeout( timeoutTimer );
				}
	
				// Dereference transport for early garbage collection
				// (no matter how long the jqXHR object will be used)
				transport = undefined;
	
				// Cache response headers
				responseHeadersString = headers || "";
	
				// Set readyState
				jqXHR.readyState = status > 0 ? 4 : 0;
	
				// Determine if successful
				isSuccess = status >= 200 && status < 300 || status === 304;
	
				// Get response data
				if ( responses ) {
					response = ajaxHandleResponses( s, jqXHR, responses );
				}
	
				// Convert no matter what (that way responseXXX fields are always set)
				response = ajaxConvert( s, response, jqXHR, isSuccess );
	
				// If successful, handle type chaining
				if ( isSuccess ) {
	
					// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
					if ( s.ifModified ) {
						modified = jqXHR.getResponseHeader( "Last-Modified" );
						if ( modified ) {
							jQuery.lastModified[ cacheURL ] = modified;
						}
						modified = jqXHR.getResponseHeader( "etag" );
						if ( modified ) {
							jQuery.etag[ cacheURL ] = modified;
						}
					}
	
					// if no content
					if ( status === 204 || s.type === "HEAD" ) {
						statusText = "nocontent";
	
					// if not modified
					} else if ( status === 304 ) {
						statusText = "notmodified";
	
					// If we have data, let's convert it
					} else {
						statusText = response.state;
						success = response.data;
						error = response.error;
						isSuccess = !error;
					}
				} else {
	
					// Extract error from statusText and normalize for non-aborts
					error = statusText;
					if ( status || !statusText ) {
						statusText = "error";
						if ( status < 0 ) {
							status = 0;
						}
					}
				}
	
				// Set data for the fake xhr object
				jqXHR.status = status;
				jqXHR.statusText = ( nativeStatusText || statusText ) + "";
	
				// Success/Error
				if ( isSuccess ) {
					deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
				} else {
					deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
				}
	
				// Status-dependent callbacks
				jqXHR.statusCode( statusCode );
				statusCode = undefined;
	
				if ( fireGlobals ) {
					globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
						[ jqXHR, s, isSuccess ? success : error ] );
				}
	
				// Complete
				completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
	
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
	
					// Handle the global AJAX counter
					if ( !( --jQuery.active ) ) {
						jQuery.event.trigger( "ajaxStop" );
					}
				}
			}
	
			return jqXHR;
		},
	
		getJSON: function( url, data, callback ) {
			return jQuery.get( url, data, callback, "json" );
		},
	
		getScript: function( url, callback ) {
			return jQuery.get( url, undefined, callback, "script" );
		}
	} );
	
	jQuery.each( [ "get", "post" ], function( i, method ) {
		jQuery[ method ] = function( url, data, callback, type ) {
	
			// Shift arguments if data argument was omitted
			if ( jQuery.isFunction( data ) ) {
				type = type || callback;
				callback = data;
				data = undefined;
			}
	
			// The url can be an options object (which then must have .url)
			return jQuery.ajax( jQuery.extend( {
				url: url,
				type: method,
				dataType: type,
				data: data,
				success: callback
			}, jQuery.isPlainObject( url ) && url ) );
		};
	} );
	
	
	jQuery._evalUrl = function( url ) {
		return jQuery.ajax( {
			url: url,
	
			// Make this explicit, since user can override this through ajaxSetup (#11264)
			type: "GET",
			dataType: "script",
			cache: true,
			async: false,
			global: false,
			"throws": true
		} );
	};
	
	
	jQuery.fn.extend( {
		wrapAll: function( html ) {
			var wrap;
	
			if ( this[ 0 ] ) {
				if ( jQuery.isFunction( html ) ) {
					html = html.call( this[ 0 ] );
				}
	
				// The elements to wrap the target around
				wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
	
				if ( this[ 0 ].parentNode ) {
					wrap.insertBefore( this[ 0 ] );
				}
	
				wrap.map( function() {
					var elem = this;
	
					while ( elem.firstElementChild ) {
						elem = elem.firstElementChild;
					}
	
					return elem;
				} ).append( this );
			}
	
			return this;
		},
	
		wrapInner: function( html ) {
			if ( jQuery.isFunction( html ) ) {
				return this.each( function( i ) {
					jQuery( this ).wrapInner( html.call( this, i ) );
				} );
			}
	
			return this.each( function() {
				var self = jQuery( this ),
					contents = self.contents();
	
				if ( contents.length ) {
					contents.wrapAll( html );
	
				} else {
					self.append( html );
				}
			} );
		},
	
		wrap: function( html ) {
			var isFunction = jQuery.isFunction( html );
	
			return this.each( function( i ) {
				jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
			} );
		},
	
		unwrap: function( selector ) {
			this.parent( selector ).not( "body" ).each( function() {
				jQuery( this ).replaceWith( this.childNodes );
			} );
			return this;
		}
	} );
	
	
	jQuery.expr.pseudos.hidden = function( elem ) {
		return !jQuery.expr.pseudos.visible( elem );
	};
	jQuery.expr.pseudos.visible = function( elem ) {
		return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
	};
	
	
	
	
	jQuery.ajaxSettings.xhr = function() {
		try {
			return new window.XMLHttpRequest();
		} catch ( e ) {}
	};
	
	var xhrSuccessStatus = {
	
			// File protocol always yields status code 0, assume 200
			0: 200,
	
			// Support: IE <=9 only
			// #1450: sometimes IE returns 1223 when it should be 204
			1223: 204
		},
		xhrSupported = jQuery.ajaxSettings.xhr();
	
	support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
	support.ajax = xhrSupported = !!xhrSupported;
	
	jQuery.ajaxTransport( function( options ) {
		var callback, errorCallback;
	
		// Cross domain only allowed if supported through XMLHttpRequest
		if ( support.cors || xhrSupported && !options.crossDomain ) {
			return {
				send: function( headers, complete ) {
					var i,
						xhr = options.xhr();
	
					xhr.open(
						options.type,
						options.url,
						options.async,
						options.username,
						options.password
					);
	
					// Apply custom fields if provided
					if ( options.xhrFields ) {
						for ( i in options.xhrFields ) {
							xhr[ i ] = options.xhrFields[ i ];
						}
					}
	
					// Override mime type if needed
					if ( options.mimeType && xhr.overrideMimeType ) {
						xhr.overrideMimeType( options.mimeType );
					}
	
					// X-Requested-With header
					// For cross-domain requests, seeing as conditions for a preflight are
					// akin to a jigsaw puzzle, we simply never set it to be sure.
					// (it can always be set on a per-request basis or even using ajaxSetup)
					// For same-domain requests, won't change header if already provided.
					if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
						headers[ "X-Requested-With" ] = "XMLHttpRequest";
					}
	
					// Set headers
					for ( i in headers ) {
						xhr.setRequestHeader( i, headers[ i ] );
					}
	
					// Callback
					callback = function( type ) {
						return function() {
							if ( callback ) {
								callback = errorCallback = xhr.onload =
									xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
	
								if ( type === "abort" ) {
									xhr.abort();
								} else if ( type === "error" ) {
	
									// Support: IE <=9 only
									// On a manual native abort, IE9 throws
									// errors on any property access that is not readyState
									if ( typeof xhr.status !== "number" ) {
										complete( 0, "error" );
									} else {
										complete(
	
											// File: protocol always yields status 0; see #8605, #14207
											xhr.status,
											xhr.statusText
										);
									}
								} else {
									complete(
										xhrSuccessStatus[ xhr.status ] || xhr.status,
										xhr.statusText,
	
										// Support: IE <=9 only
										// IE9 has no XHR2 but throws on binary (trac-11426)
										// For XHR2 non-text, let the caller handle it (gh-2498)
										( xhr.responseType || "text" ) !== "text"  ||
										typeof xhr.responseText !== "string" ?
											{ binary: xhr.response } :
											{ text: xhr.responseText },
										xhr.getAllResponseHeaders()
									);
								}
							}
						};
					};
	
					// Listen to events
					xhr.onload = callback();
					errorCallback = xhr.onerror = callback( "error" );
	
					// Support: IE 9 only
					// Use onreadystatechange to replace onabort
					// to handle uncaught aborts
					if ( xhr.onabort !== undefined ) {
						xhr.onabort = errorCallback;
					} else {
						xhr.onreadystatechange = function() {
	
							// Check readyState before timeout as it changes
							if ( xhr.readyState === 4 ) {
	
								// Allow onerror to be called first,
								// but that will not handle a native abort
								// Also, save errorCallback to a variable
								// as xhr.onerror cannot be accessed
								window.setTimeout( function() {
									if ( callback ) {
										errorCallback();
									}
								} );
							}
						};
					}
	
					// Create the abort callback
					callback = callback( "abort" );
	
					try {
	
						// Do send the request (this may raise an exception)
						xhr.send( options.hasContent && options.data || null );
					} catch ( e ) {
	
						// #14683: Only rethrow if this hasn't been notified as an error yet
						if ( callback ) {
							throw e;
						}
					}
				},
	
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
	jQuery.ajaxPrefilter( function( s ) {
		if ( s.crossDomain ) {
			s.contents.script = false;
		}
	} );
	
	// Install script dataType
	jQuery.ajaxSetup( {
		accepts: {
			script: "text/javascript, application/javascript, " +
				"application/ecmascript, application/x-ecmascript"
		},
		contents: {
			script: /\b(?:java|ecma)script\b/
		},
		converters: {
			"text script": function( text ) {
				jQuery.globalEval( text );
				return text;
			}
		}
	} );
	
	// Handle cache's special case and crossDomain
	jQuery.ajaxPrefilter( "script", function( s ) {
		if ( s.cache === undefined ) {
			s.cache = false;
		}
		if ( s.crossDomain ) {
			s.type = "GET";
		}
	} );
	
	// Bind script tag hack transport
	jQuery.ajaxTransport( "script", function( s ) {
	
		// This transport only deals with cross domain requests
		if ( s.crossDomain ) {
			var script, callback;
			return {
				send: function( _, complete ) {
					script = jQuery( "<script>" ).prop( {
						charset: s.scriptCharset,
						src: s.url
					} ).on(
						"load error",
						callback = function( evt ) {
							script.remove();
							callback = null;
							if ( evt ) {
								complete( evt.type === "error" ? 404 : 200, evt.type );
							}
						}
					);
	
					// Use native DOM manipulation to avoid our domManip AJAX trickery
					document.head.appendChild( script[ 0 ] );
				},
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	var oldCallbacks = [],
		rjsonp = /(=)\?(?=&|$)|\?\?/;
	
	// Default jsonp settings
	jQuery.ajaxSetup( {
		jsonp: "callback",
		jsonpCallback: function() {
			var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
			this[ callback ] = true;
			return callback;
		}
	} );
	
	// Detect, normalize options and install callbacks for jsonp requests
	jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
	
		var callbackName, overwritten, responseContainer,
			jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
				"url" :
				typeof s.data === "string" &&
					( s.contentType || "" )
						.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
					rjsonp.test( s.data ) && "data"
			);
	
		// Handle iff the expected data type is "jsonp" or we have a parameter to set
		if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
	
			// Get callback name, remembering preexisting value associated with it
			callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
				s.jsonpCallback() :
				s.jsonpCallback;
	
			// Insert callback into url or form data
			if ( jsonProp ) {
				s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
			} else if ( s.jsonp !== false ) {
				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
			}
	
			// Use data converter to retrieve json after script execution
			s.converters[ "script json" ] = function() {
				if ( !responseContainer ) {
					jQuery.error( callbackName + " was not called" );
				}
				return responseContainer[ 0 ];
			};
	
			// Force json dataType
			s.dataTypes[ 0 ] = "json";
	
			// Install callback
			overwritten = window[ callbackName ];
			window[ callbackName ] = function() {
				responseContainer = arguments;
			};
	
			// Clean-up function (fires after converters)
			jqXHR.always( function() {
	
				// If previous value didn't exist - remove it
				if ( overwritten === undefined ) {
					jQuery( window ).removeProp( callbackName );
	
				// Otherwise restore preexisting value
				} else {
					window[ callbackName ] = overwritten;
				}
	
				// Save back as free
				if ( s[ callbackName ] ) {
	
					// Make sure that re-using the options doesn't screw things around
					s.jsonpCallback = originalSettings.jsonpCallback;
	
					// Save the callback name for future use
					oldCallbacks.push( callbackName );
				}
	
				// Call if it was a function and we have a response
				if ( responseContainer && jQuery.isFunction( overwritten ) ) {
					overwritten( responseContainer[ 0 ] );
				}
	
				responseContainer = overwritten = undefined;
			} );
	
			// Delegate to script
			return "script";
		}
	} );
	
	
	
	
	// Support: Safari 8 only
	// In Safari 8 documents created via document.implementation.createHTMLDocument
	// collapse sibling forms: the second one becomes a child of the first one.
	// Because of that, this security measure has to be disabled in Safari 8.
	// https://bugs.webkit.org/show_bug.cgi?id=137337
	support.createHTMLDocument = ( function() {
		var body = document.implementation.createHTMLDocument( "" ).body;
		body.innerHTML = "<form></form><form></form>";
		return body.childNodes.length === 2;
	} )();
	
	
	// Argument "data" should be string of html
	// context (optional): If specified, the fragment will be created in this context,
	// defaults to document
	// keepScripts (optional): If true, will include scripts passed in the html string
	jQuery.parseHTML = function( data, context, keepScripts ) {
		if ( typeof data !== "string" ) {
			return [];
		}
		if ( typeof context === "boolean" ) {
			keepScripts = context;
			context = false;
		}
	
		var base, parsed, scripts;
	
		if ( !context ) {
	
			// Stop scripts or inline event handlers from being executed immediately
			// by using document.implementation
			if ( support.createHTMLDocument ) {
				context = document.implementation.createHTMLDocument( "" );
	
				// Set the base href for the created document
				// so any parsed elements with URLs
				// are based on the document's URL (gh-2965)
				base = context.createElement( "base" );
				base.href = document.location.href;
				context.head.appendChild( base );
			} else {
				context = document;
			}
		}
	
		parsed = rsingleTag.exec( data );
		scripts = !keepScripts && [];
	
		// Single tag
		if ( parsed ) {
			return [ context.createElement( parsed[ 1 ] ) ];
		}
	
		parsed = buildFragment( [ data ], context, scripts );
	
		if ( scripts && scripts.length ) {
			jQuery( scripts ).remove();
		}
	
		return jQuery.merge( [], parsed.childNodes );
	};
	
	
	/**
	 * Load a url into a page
	 */
	jQuery.fn.load = function( url, params, callback ) {
		var selector, type, response,
			self = this,
			off = url.indexOf( " " );
	
		if ( off > -1 ) {
			selector = stripAndCollapse( url.slice( off ) );
			url = url.slice( 0, off );
		}
	
		// If it's a function
		if ( jQuery.isFunction( params ) ) {
	
			// We assume that it's the callback
			callback = params;
			params = undefined;
	
		// Otherwise, build a param string
		} else if ( params && typeof params === "object" ) {
			type = "POST";
		}
	
		// If we have elements to modify, make the request
		if ( self.length > 0 ) {
			jQuery.ajax( {
				url: url,
	
				// If "type" variable is undefined, then "GET" method will be used.
				// Make value of this field explicit since
				// user can override it through ajaxSetup method
				type: type || "GET",
				dataType: "html",
				data: params
			} ).done( function( responseText ) {
	
				// Save response for use in complete callback
				response = arguments;
	
				self.html( selector ?
	
					// If a selector was specified, locate the right elements in a dummy div
					// Exclude scripts to avoid IE 'Permission Denied' errors
					jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
	
					// Otherwise use the full result
					responseText );
	
			// If the request succeeds, this function gets "data", "status", "jqXHR"
			// but they are ignored because response was set above.
			// If it fails, this function gets "jqXHR", "status", "error"
			} ).always( callback && function( jqXHR, status ) {
				self.each( function() {
					callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
				} );
			} );
		}
	
		return this;
	};
	
	
	
	
	// Attach a bunch of functions for handling common AJAX events
	jQuery.each( [
		"ajaxStart",
		"ajaxStop",
		"ajaxComplete",
		"ajaxError",
		"ajaxSuccess",
		"ajaxSend"
	], function( i, type ) {
		jQuery.fn[ type ] = function( fn ) {
			return this.on( type, fn );
		};
	} );
	
	
	
	
	jQuery.expr.pseudos.animated = function( elem ) {
		return jQuery.grep( jQuery.timers, function( fn ) {
			return elem === fn.elem;
		} ).length;
	};
	
	
	
	
	jQuery.offset = {
		setOffset: function( elem, options, i ) {
			var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
				position = jQuery.css( elem, "position" ),
				curElem = jQuery( elem ),
				props = {};
	
			// Set position first, in-case top/left are set even on static elem
			if ( position === "static" ) {
				elem.style.position = "relative";
			}
	
			curOffset = curElem.offset();
			curCSSTop = jQuery.css( elem, "top" );
			curCSSLeft = jQuery.css( elem, "left" );
			calculatePosition = ( position === "absolute" || position === "fixed" ) &&
				( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
	
			// Need to be able to calculate position if either
			// top or left is auto and position is either absolute or fixed
			if ( calculatePosition ) {
				curPosition = curElem.position();
				curTop = curPosition.top;
				curLeft = curPosition.left;
	
			} else {
				curTop = parseFloat( curCSSTop ) || 0;
				curLeft = parseFloat( curCSSLeft ) || 0;
			}
	
			if ( jQuery.isFunction( options ) ) {
	
				// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
				options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
			}
	
			if ( options.top != null ) {
				props.top = ( options.top - curOffset.top ) + curTop;
			}
			if ( options.left != null ) {
				props.left = ( options.left - curOffset.left ) + curLeft;
			}
	
			if ( "using" in options ) {
				options.using.call( elem, props );
	
			} else {
				curElem.css( props );
			}
		}
	};
	
	jQuery.fn.extend( {
		offset: function( options ) {
	
			// Preserve chaining for setter
			if ( arguments.length ) {
				return options === undefined ?
					this :
					this.each( function( i ) {
						jQuery.offset.setOffset( this, options, i );
					} );
			}
	
			var doc, docElem, rect, win,
				elem = this[ 0 ];
	
			if ( !elem ) {
				return;
			}
	
			// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
			// Support: IE <=11 only
			// Running getBoundingClientRect on a
			// disconnected node in IE throws an error
			if ( !elem.getClientRects().length ) {
				return { top: 0, left: 0 };
			}
	
			rect = elem.getBoundingClientRect();
	
			doc = elem.ownerDocument;
			docElem = doc.documentElement;
			win = doc.defaultView;
	
			return {
				top: rect.top + win.pageYOffset - docElem.clientTop,
				left: rect.left + win.pageXOffset - docElem.clientLeft
			};
		},
	
		position: function() {
			if ( !this[ 0 ] ) {
				return;
			}
	
			var offsetParent, offset,
				elem = this[ 0 ],
				parentOffset = { top: 0, left: 0 };
	
			// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
			// because it is its only offset parent
			if ( jQuery.css( elem, "position" ) === "fixed" ) {
	
				// Assume getBoundingClientRect is there when computed position is fixed
				offset = elem.getBoundingClientRect();
	
			} else {
	
				// Get *real* offsetParent
				offsetParent = this.offsetParent();
	
				// Get correct offsets
				offset = this.offset();
				if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
					parentOffset = offsetParent.offset();
				}
	
				// Add offsetParent borders
				parentOffset = {
					top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
					left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
				};
			}
	
			// Subtract parent offsets and element margins
			return {
				top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
				left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
			};
		},
	
		// This method will return documentElement in the following cases:
		// 1) For the element inside the iframe without offsetParent, this method will return
		//    documentElement of the parent window
		// 2) For the hidden or detached element
		// 3) For body or html element, i.e. in case of the html node - it will return itself
		//
		// but those exceptions were never presented as a real life use-cases
		// and might be considered as more preferable results.
		//
		// This logic, however, is not guaranteed and can change at any point in the future
		offsetParent: function() {
			return this.map( function() {
				var offsetParent = this.offsetParent;
	
				while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
					offsetParent = offsetParent.offsetParent;
				}
	
				return offsetParent || documentElement;
			} );
		}
	} );
	
	// Create scrollLeft and scrollTop methods
	jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
		var top = "pageYOffset" === prop;
	
		jQuery.fn[ method ] = function( val ) {
			return access( this, function( elem, method, val ) {
	
				// Coalesce documents and windows
				var win;
				if ( jQuery.isWindow( elem ) ) {
					win = elem;
				} else if ( elem.nodeType === 9 ) {
					win = elem.defaultView;
				}
	
				if ( val === undefined ) {
					return win ? win[ prop ] : elem[ method ];
				}
	
				if ( win ) {
					win.scrollTo(
						!top ? val : win.pageXOffset,
						top ? val : win.pageYOffset
					);
	
				} else {
					elem[ method ] = val;
				}
			}, method, val, arguments.length );
		};
	} );
	
	// Support: Safari <=7 - 9.1, Chrome <=37 - 49
	// Add the top/left cssHooks using jQuery.fn.position
	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
	// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
	// getComputedStyle returns percent when specified for top/left/bottom/right;
	// rather than make the css module depend on the offset module, just check for it here
	jQuery.each( [ "top", "left" ], function( i, prop ) {
		jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
			function( elem, computed ) {
				if ( computed ) {
					computed = curCSS( elem, prop );
	
					// If curCSS returns percentage, fallback to offset
					return rnumnonpx.test( computed ) ?
						jQuery( elem ).position()[ prop ] + "px" :
						computed;
				}
			}
		);
	} );
	
	
	// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
	jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
		jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
			function( defaultExtra, funcName ) {
	
			// Margin is only for outerHeight, outerWidth
			jQuery.fn[ funcName ] = function( margin, value ) {
				var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
					extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
	
				return access( this, function( elem, type, value ) {
					var doc;
	
					if ( jQuery.isWindow( elem ) ) {
	
						// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
						return funcName.indexOf( "outer" ) === 0 ?
							elem[ "inner" + name ] :
							elem.document.documentElement[ "client" + name ];
					}
	
					// Get document width or height
					if ( elem.nodeType === 9 ) {
						doc = elem.documentElement;
	
						// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
						// whichever is greatest
						return Math.max(
							elem.body[ "scroll" + name ], doc[ "scroll" + name ],
							elem.body[ "offset" + name ], doc[ "offset" + name ],
							doc[ "client" + name ]
						);
					}
	
					return value === undefined ?
	
						// Get width or height on the element, requesting but not forcing parseFloat
						jQuery.css( elem, type, extra ) :
	
						// Set width or height on the element
						jQuery.style( elem, type, value, extra );
				}, type, chainable ? margin : undefined, chainable );
			};
		} );
	} );
	
	
	jQuery.fn.extend( {
	
		bind: function( types, data, fn ) {
			return this.on( types, null, data, fn );
		},
		unbind: function( types, fn ) {
			return this.off( types, null, fn );
		},
	
		delegate: function( selector, types, data, fn ) {
			return this.on( types, selector, data, fn );
		},
		undelegate: function( selector, types, fn ) {
	
			// ( namespace ) or ( selector, types [, fn] )
			return arguments.length === 1 ?
				this.off( selector, "**" ) :
				this.off( types, selector || "**", fn );
		}
	} );
	
	jQuery.holdReady = function( hold ) {
		if ( hold ) {
			jQuery.readyWait++;
		} else {
			jQuery.ready( true );
		}
	};
	jQuery.isArray = Array.isArray;
	jQuery.parseJSON = JSON.parse;
	jQuery.nodeName = nodeName;
	
	
	
	
	// Register as a named AMD module, since jQuery can be concatenated with other
	// files that may use define, but not via a proper concatenation script that
	// understands anonymous AMD modules. A named AMD is safest and most robust
	// way to register. Lowercase jquery is used because AMD module names are
	// derived from file names, and jQuery is normally delivered in a lowercase
	// file name. Do this after creating the global so that if an AMD module wants
	// to call noConflict to hide this version of jQuery, it will work.
	
	// Note that for maximum portability, libraries that are not jQuery should
	// declare themselves as anonymous modules, and avoid setting a global if an
	// AMD loader is present. jQuery is a special case. For more information, see
	// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
	
	if ( true ) {
		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
			return jQuery;
		}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	}
	
	
	
	
	var
	
		// Map over jQuery in case of overwrite
		_jQuery = window.jQuery,
	
		// Map over the $ in case of overwrite
		_$ = window.$;
	
	jQuery.noConflict = function( deep ) {
		if ( window.$ === jQuery ) {
			window.$ = _$;
		}
	
		if ( deep && window.jQuery === jQuery ) {
			window.jQuery = _jQuery;
		}
	
		return jQuery;
	};
	
	// Expose jQuery and $ identifiers, even in AMD
	// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
	// and CommonJS for browser emulators (#13566)
	if ( !noGlobal ) {
		window.jQuery = window.$ = jQuery;
	}
	
	
	
	
	return jQuery;
	} );


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*
	 This file contains substantial portions of https://github.com/akre54/Backbone.NativeView/blob/521188d9554b53d95d70ed34f878d8ac9fc10df2/backbone.nativeview.js, which has the following license:
	
	(c) 2015 Adam Krebs, Jimmy Yuen Ho Wong
	Backbone.NativeView may be freely distributed under the MIT license.
	
	Copyright (c) 2014 Adam Krebs
	
	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:
	
	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.
	
	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
	
	*/
	var Backbone = __webpack_require__(168);
	// Caches a local reference to `Element.prototype` for faster access.
	var ElementProto = Element.prototype; // : typeof Element = (typeof Element !== 'undefined' && Element.prototype) || {};
	// Find the right `Element#matches` for IE>=9 and modern browsers.
	var matchesSelector = ElementProto.matches ||
	    ElementProto['webkitMatchesSelector'] ||
	    ElementProto['mozMatchesSelector'] ||
	    ElementProto['msMatchesSelector'] ||
	    ElementProto['oMatchesSelector'] ||
	    function matches(selector) {
	        var matches = (this.document || this.ownerDocument).querySelectorAll(selector);
	        var i = matches.length;
	        while (--i >= 0 && matches.item(i) !== this) {
	            continue;
	        }
	        return i > -1;
	    };
	var NativeView = /** @class */ (function (_super) {
	    __extends(NativeView, _super);
	    function NativeView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    NativeView.prototype._removeElement = function () {
	        this.undelegateEvents();
	        if (this.el.parentNode) {
	            this.el.parentNode.removeChild(this.el);
	        }
	    };
	    // Apply the `element` to the view.
	    NativeView.prototype._setElement = function (element) {
	        this.el = element;
	    };
	    // Set a hash of attributes to the view's `el`. We use the "prop" version
	    // if available, falling back to `setAttribute` for the catch-all.
	    NativeView.prototype._setAttributes = function (attrs) {
	        for (var attr in attrs) {
	            attr in this.el ? this.el[attr] = attrs[attr] : this.el.setAttribute(attr, attrs[attr]);
	        }
	    };
	    /**
	     * Make an event delegation handler for the given `eventName` and `selector`
	     * and attach it to `this.el`.
	     * If selector is empty, the listener will be bound to `this.el`. If not, a
	     * new handler that will recursively traverse up the event target's DOM
	     * hierarchy looking for a node that matches the selector. If one is found,
	     * the event's `delegateTarget` property is set to it and the return the
	     * result of calling bound `listener` with the parameters given to the
	     * handler.
	     *
	     * This does not properly handle selectors for things like focus and blur (see
	     * https://github.com/jquery/jquery/blob/7d21f02b9ec9f655583e898350badf89165ed4d5/src/event.js#L442
	     * for some similar exceptional cases).
	     */
	    NativeView.prototype.delegate = function (eventName, selector, listener) {
	        if (typeof selector !== 'string') {
	            listener = selector;
	            selector = null;
	        }
	        // We have to initialize this here, instead of in the constructor, because the
	        // super constructor eventually calls this method before we get a chance to initialize
	        // this._domEvents to an empty list.
	        if (this._domEvents === void 0) {
	            this._domEvents = [];
	        }
	        var root = this.el;
	        var handler = selector ? function (e) {
	            var node = e.target || e.srcElement;
	            for (; node && node !== root; node = node.parentNode) {
	                if (matchesSelector.call(node, selector)) {
	                    e.delegateTarget = node;
	                    if (listener.handleEvent) {
	                        return listener.handleEvent(e);
	                    }
	                    else {
	                        return listener(e);
	                    }
	                }
	            }
	        } : listener;
	        this.el.addEventListener(eventName, handler, false);
	        this._domEvents.push({ eventName: eventName, handler: handler, listener: listener, selector: selector });
	        return handler;
	    };
	    // Remove a single delegated event. Either `eventName` or `selector` must
	    // be included, `selector` and `listener` are optional.
	    NativeView.prototype.undelegate = function (eventName, selector, listener) {
	        if (typeof selector === 'function') {
	            listener = selector;
	            selector = null;
	        }
	        if (this.el && this._domEvents) {
	            var handlers = this._domEvents.slice();
	            var i = handlers.length;
	            while (i--) {
	                var item = handlers[i];
	                var match = item.eventName === eventName &&
	                    (listener ? item.listener === listener : true) &&
	                    (selector ? item.selector === selector : true);
	                if (!match) {
	                    continue;
	                }
	                this.el.removeEventListener(item.eventName, item.handler, false);
	                this._domEvents.splice(i, 1);
	            }
	        }
	        return this;
	    };
	    // Remove all events created with `delegate` from `el`
	    NativeView.prototype.undelegateEvents = function () {
	        if (this.el && this._domEvents) {
	            var len = this._domEvents.length;
	            for (var i = 0; i < len; i++) {
	                var item = this._domEvents[i];
	                this.el.removeEventListener(item.eventName, item.handler, false);
	            }
	            this._domEvents.length = 0;
	        }
	        return this;
	    };
	    return NativeView;
	}(Backbone.View));
	exports.NativeView = NativeView;


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

	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__webpack_require__(173));
	__export(__webpack_require__(174));
	__export(__webpack_require__(205));
	__export(__webpack_require__(207));
	__export(__webpack_require__(212));
	__export(__webpack_require__(214));
	__export(__webpack_require__(215));
	__export(__webpack_require__(218));
	__export(__webpack_require__(219));
	__export(__webpack_require__(200));
	__export(__webpack_require__(213));
	__export(__webpack_require__(220));
	__export(__webpack_require__(206));
	__export(__webpack_require__(204));
	__export(__webpack_require__(221));
	__export(__webpack_require__(222));
	__export(__webpack_require__(223));
	__export(__webpack_require__(224));
	__export(__webpack_require__(225));
	__export(__webpack_require__(217));
	__export(__webpack_require__(226));
	__export(__webpack_require__(203));
	__export(__webpack_require__(202));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A sizer object for use with the box engine layout functions.
	 *
	 * #### Notes
	 * A box sizer holds the geometry information for an object along an
	 * arbitrary layout orientation.
	 *
	 * For best performance, this class should be treated as a raw data
	 * struct. It should not typically be subclassed.
	 */
	var BoxSizer = (function () {
	    function BoxSizer() {
	        /**
	         * The preferred size for the sizer.
	         *
	         * #### Notes
	         * The sizer will be given this initial size subject to its size
	         * bounds. The sizer will not deviate from this size unless such
	         * deviation is required to fit into the available layout space.
	         *
	         * There is no limit to this value, but it will be clamped to the
	         * bounds defined by [[minSize]] and [[maxSize]].
	         *
	         * The default value is `0`.
	         */
	        this.sizeHint = 0;
	        /**
	         * The minimum size of the sizer.
	         *
	         * #### Notes
	         * The sizer will never be sized less than this value, even if
	         * it means the sizer will overflow the available layout space.
	         *
	         * It is assumed that this value lies in the range `[0, Infinity)`
	         * and that it is `<=` to [[maxSize]]. Failure to adhere to this
	         * constraint will yield undefined results.
	         *
	         * The default value is `0`.
	         */
	        this.minSize = 0;
	        /**
	         * The maximum size of the sizer.
	         *
	         * #### Notes
	         * The sizer will never be sized greater than this value, even if
	         * it means the sizer will underflow the available layout space.
	         *
	         * It is assumed that this value lies in the range `[0, Infinity]`
	         * and that it is `>=` to [[minSize]]. Failure to adhere to this
	         * constraint will yield undefined results.
	         *
	         * The default value is `Infinity`.
	         */
	        this.maxSize = Infinity;
	        /**
	         * The stretch factor for the sizer.
	         *
	         * #### Notes
	         * This controls how much the sizer stretches relative to its sibling
	         * sizers when layout space is distributed. A stretch factor of zero
	         * is special and will cause the sizer to only be resized after all
	         * other sizers with a stretch factor greater than zero have been
	         * resized to their limits.
	         *
	         * It is assumed that this value is an integer that lies in the range
	         * `[0, Infinity)`. Failure to adhere to this constraint will yield
	         * undefined results.
	         *
	         * The default value is `1`.
	         */
	        this.stretch = 1;
	        /**
	         * The computed size of the sizer.
	         *
	         * #### Notes
	         * This value is the output of a call to [[boxCalc]]. It represents
	         * the computed size for the object along the layout orientation,
	         * and will always lie in the range `[minSize, maxSize]`.
	         *
	         * This value is output only.
	         *
	         * Changing this value will have no effect.
	         */
	        this.size = 0;
	        /**
	         * An internal storage property for the layout algorithm.
	         *
	         * #### Notes
	         * This value is used as temporary storage by the layout algorithm.
	         *
	         * Changing this value will have no effect.
	         */
	        this.done = false;
	    }
	    return BoxSizer;
	}());
	exports.BoxSizer = BoxSizer;
	/**
	 * The namespace for the box engine layout functions.
	 */
	var BoxEngine;
	(function (BoxEngine) {
	    /**
	     * Calculate the optimal layout sizes for a sequence of box sizers.
	     *
	     * This distributes the available layout space among the box sizers
	     * according to the following algorithm:
	     *
	     * 1. Initialize the sizers's size to its size hint and compute the
	     *    sums for each of size hint, min size, and max size.
	     *
	     * 2. If the total size hint equals the available space, return.
	     *
	     * 3. If the available space is less than the total min size, set all
	     *    sizers to their min size and return.
	     *
	     * 4. If the available space is greater than the total max size, set
	     *    all sizers to their max size and return.
	     *
	     * 5. If the layout space is less than the total size hint, distribute
	     *    the negative delta as follows:
	     *
	     *    a. Shrink each sizer with a stretch factor greater than zero by
	     *       an amount proportional to the negative space and the sum of
	     *       stretch factors. If the sizer reaches its min size, remove
	     *       it and its stretch factor from the computation.
	     *
	     *    b. If after adjusting all stretch sizers there remains negative
	     *       space, distribute the space equally among the sizers with a
	     *       stretch factor of zero. If a sizer reaches its min size,
	     *       remove it from the computation.
	     *
	     * 6. If the layout space is greater than the total size hint,
	     *    distribute the positive delta as follows:
	     *
	     *    a. Expand each sizer with a stretch factor greater than zero by
	     *       an amount proportional to the postive space and the sum of
	     *       stretch factors. If the sizer reaches its max size, remove
	     *       it and its stretch factor from the computation.
	     *
	     *    b. If after adjusting all stretch sizers there remains positive
	     *       space, distribute the space equally among the sizers with a
	     *       stretch factor of zero. If a sizer reaches its max size,
	     *       remove it from the computation.
	     *
	     * 7. return
	     *
	     * @param sizers - The sizers for a particular layout line.
	     *
	     * @param space - The available layout space for the sizers.
	     *
	     * @returns The delta between the provided available space and the
	     *   actual consumed space. This value will be zero if the sizers
	     *   can be adjusted to fit, negative if the available space is too
	     *   small, and positive if the available space is too large.
	     *
	     * #### Notes
	     * The [[size]] of each sizer is updated with the computed size.
	     *
	     * This function can be called at any time to recompute the layout for
	     * an existing sequence of sizers. The previously computed results will
	     * have no effect on the new output. It is therefore not necessary to
	     * create new sizer objects on each resize event.
	     */
	    function calc(sizers, space) {
	        // Bail early if there is nothing to do.
	        var count = sizers.length;
	        if (count === 0) {
	            return space;
	        }
	        // Setup the size and stretch counters.
	        var totalMin = 0;
	        var totalMax = 0;
	        var totalSize = 0;
	        var totalStretch = 0;
	        var stretchCount = 0;
	        // Setup the sizers and compute the totals.
	        for (var i = 0; i < count; ++i) {
	            var sizer = sizers[i];
	            var min = sizer.minSize;
	            var max = sizer.maxSize;
	            var hint = sizer.sizeHint;
	            sizer.done = false;
	            sizer.size = Math.max(min, Math.min(hint, max));
	            totalSize += sizer.size;
	            totalMin += min;
	            totalMax += max;
	            if (sizer.stretch > 0) {
	                totalStretch += sizer.stretch;
	                stretchCount++;
	            }
	        }
	        // If the space is equal to the total size, return early.
	        if (space === totalSize) {
	            return 0;
	        }
	        // If the space is less than the total min, minimize each sizer.
	        if (space <= totalMin) {
	            for (var i = 0; i < count; ++i) {
	                var sizer = sizers[i];
	                sizer.size = sizer.minSize;
	            }
	            return space - totalMin;
	        }
	        // If the space is greater than the total max, maximize each sizer.
	        if (space >= totalMax) {
	            for (var i = 0; i < count; ++i) {
	                var sizer = sizers[i];
	                sizer.size = sizer.maxSize;
	            }
	            return space - totalMax;
	        }
	        // The loops below perform sub-pixel precision sizing. A near zero
	        // value is used for compares instead of zero to ensure that the
	        // loop terminates when the subdivided space is reasonably small.
	        var nearZero = 0.01;
	        // A counter which is decremented each time a sizer is resized to
	        // its limit. This ensures the loops terminate even if there is
	        // space remaining to distribute.
	        var notDoneCount = count;
	        // Distribute negative delta space.
	        if (space < totalSize) {
	            // Shrink each stretchable sizer by an amount proportional to its
	            // stretch factor. If a sizer reaches its min size it's marked as
	            // done. The loop progresses in phases where each sizer is given
	            // a chance to consume its fair share for the pass, regardless of
	            // whether a sizer before it reached its limit. This continues
	            // until the stretchable sizers or the free space is exhausted.
	            var freeSpace = totalSize - space;
	            while (stretchCount > 0 && freeSpace > nearZero) {
	                var distSpace = freeSpace;
	                var distStretch = totalStretch;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done || sizer.stretch === 0) {
	                        continue;
	                    }
	                    var amt = sizer.stretch * distSpace / distStretch;
	                    if (sizer.size - amt <= sizer.minSize) {
	                        freeSpace -= sizer.size - sizer.minSize;
	                        totalStretch -= sizer.stretch;
	                        sizer.size = sizer.minSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                        stretchCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size -= amt;
	                    }
	                }
	            }
	            // Distribute any remaining space evenly among the non-stretchable
	            // sizers. This progresses in phases in the same manner as above.
	            while (notDoneCount > 0 && freeSpace > nearZero) {
	                var amt = freeSpace / notDoneCount;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done) {
	                        continue;
	                    }
	                    if (sizer.size - amt <= sizer.minSize) {
	                        freeSpace -= sizer.size - sizer.minSize;
	                        sizer.size = sizer.minSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size -= amt;
	                    }
	                }
	            }
	        }
	        else {
	            // Expand each stretchable sizer by an amount proportional to its
	            // stretch factor. If a sizer reaches its max size it's marked as
	            // done. The loop progresses in phases where each sizer is given
	            // a chance to consume its fair share for the pass, regardless of
	            // whether a sizer before it reached its limit. This continues
	            // until the stretchable sizers or the free space is exhausted.
	            var freeSpace = space - totalSize;
	            while (stretchCount > 0 && freeSpace > nearZero) {
	                var distSpace = freeSpace;
	                var distStretch = totalStretch;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done || sizer.stretch === 0) {
	                        continue;
	                    }
	                    var amt = sizer.stretch * distSpace / distStretch;
	                    if (sizer.size + amt >= sizer.maxSize) {
	                        freeSpace -= sizer.maxSize - sizer.size;
	                        totalStretch -= sizer.stretch;
	                        sizer.size = sizer.maxSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                        stretchCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size += amt;
	                    }
	                }
	            }
	            // Distribute any remaining space evenly among the non-stretchable
	            // sizers. This progresses in phases in the same manner as above.
	            while (notDoneCount > 0 && freeSpace > nearZero) {
	                var amt = freeSpace / notDoneCount;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done) {
	                        continue;
	                    }
	                    if (sizer.size + amt >= sizer.maxSize) {
	                        freeSpace -= sizer.maxSize - sizer.size;
	                        sizer.size = sizer.maxSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size += amt;
	                    }
	                }
	            }
	        }
	        // Indicate that the consumed space equals the available space.
	        return 0;
	    }
	    BoxEngine.calc = calc;
	    /**
	     * Adjust a sizer by a delta and update its neighbors accordingly.
	     *
	     * @param sizers - The sizers which should be adjusted.
	     *
	     * @param index - The index of the sizer to grow.
	     *
	     * @param delta - The amount to adjust the sizer, positive or negative.
	     *
	     * #### Notes
	     * This will adjust the indicated sizer by the specified amount, along
	     * with the sizes of the appropriate neighbors, subject to the limits
	     * specified by each of the sizers.
	     *
	     * This is useful when implementing box layouts where the boundaries
	     * between the sizers are interactively adjustable by the user.
	     */
	    function adjust(sizers, index, delta) {
	        // Bail early when there is nothing to do.
	        if (sizers.length === 0 || delta === 0) {
	            return;
	        }
	        // Dispatch to the proper implementation.
	        if (delta > 0) {
	            growSizer(sizers, index, delta);
	        }
	        else {
	            shrinkSizer(sizers, index, -delta);
	        }
	    }
	    BoxEngine.adjust = adjust;
	    /**
	     * Grow a sizer by a positive delta and adjust neighbors.
	     */
	    function growSizer(sizers, index, delta) {
	        // Compute how much the items to the left can expand.
	        var growLimit = 0;
	        for (var i = 0; i <= index; ++i) {
	            var sizer = sizers[i];
	            growLimit += sizer.maxSize - sizer.size;
	        }
	        // Compute how much the items to the right can shrink.
	        var shrinkLimit = 0;
	        for (var i = index + 1, n = sizers.length; i < n; ++i) {
	            var sizer = sizers[i];
	            shrinkLimit += sizer.size - sizer.minSize;
	        }
	        // Clamp the delta adjustment to the limits.
	        delta = Math.min(delta, growLimit, shrinkLimit);
	        // Grow the sizers to the left by the delta.
	        var grow = delta;
	        for (var i = index; i >= 0 && grow > 0; --i) {
	            var sizer = sizers[i];
	            var limit = sizer.maxSize - sizer.size;
	            if (limit >= grow) {
	                sizer.sizeHint = sizer.size + grow;
	                grow = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size + limit;
	                grow -= limit;
	            }
	        }
	        // Shrink the sizers to the right by the delta.
	        var shrink = delta;
	        for (var i = index + 1, n = sizers.length; i < n && shrink > 0; ++i) {
	            var sizer = sizers[i];
	            var limit = sizer.size - sizer.minSize;
	            if (limit >= shrink) {
	                sizer.sizeHint = sizer.size - shrink;
	                shrink = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size - limit;
	                shrink -= limit;
	            }
	        }
	    }
	    /**
	     * Shrink a sizer by a positive delta and adjust neighbors.
	     */
	    function shrinkSizer(sizers, index, delta) {
	        // Compute how much the items to the right can expand.
	        var growLimit = 0;
	        for (var i = index + 1, n = sizers.length; i < n; ++i) {
	            var sizer = sizers[i];
	            growLimit += sizer.maxSize - sizer.size;
	        }
	        // Compute how much the items to the left can shrink.
	        var shrinkLimit = 0;
	        for (var i = 0; i <= index; ++i) {
	            var sizer = sizers[i];
	            shrinkLimit += sizer.size - sizer.minSize;
	        }
	        // Clamp the delta adjustment to the limits.
	        delta = Math.min(delta, growLimit, shrinkLimit);
	        // Grow the sizers to the right by the delta.
	        var grow = delta;
	        for (var i = index + 1, n = sizers.length; i < n && grow > 0; ++i) {
	            var sizer = sizers[i];
	            var limit = sizer.maxSize - sizer.size;
	            if (limit >= grow) {
	                sizer.sizeHint = sizer.size + grow;
	                grow = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size + limit;
	                grow -= limit;
	            }
	        }
	        // Shrink the sizers to the left by the delta.
	        var shrink = delta;
	        for (var i = index; i >= 0 && shrink > 0; --i) {
	            var sizer = sizers[i];
	            var limit = sizer.size - sizer.minSize;
	            if (limit >= shrink) {
	                sizer.sizeHint = sizer.size - shrink;
	                shrink = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size - limit;
	                shrink -= limit;
	            }
	        }
	    }
	})(BoxEngine = exports.BoxEngine || (exports.BoxEngine = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var messaging_1 = __webpack_require__(196);
	var properties_1 = __webpack_require__(199);
	var boxengine_1 = __webpack_require__(173);
	var layout_1 = __webpack_require__(200);
	var panellayout_1 = __webpack_require__(204);
	var widget_1 = __webpack_require__(202);
	/**
	 * A layout which arranges its widgets in a single row or column.
	 */
	var BoxLayout = (function (_super) {
	    __extends(BoxLayout, _super);
	    /**
	     * Construct a new box layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function BoxLayout(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._fixed = 0;
	        _this._spacing = 4;
	        _this._dirty = false;
	        _this._sizers = [];
	        _this._items = [];
	        _this._box = null;
	        _this._alignment = 'start';
	        _this._direction = 'top-to-bottom';
	        if (options.direction !== undefined) {
	            _this._direction = options.direction;
	        }
	        if (options.alignment !== undefined) {
	            _this._alignment = options.alignment;
	        }
	        if (options.spacing !== undefined) {
	            _this._spacing = Private.clampSpacing(options.spacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    BoxLayout.prototype.dispose = function () {
	        // Dispose of the layout items.
	        algorithm_1.each(this._items, function (item) { item.dispose(); });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        this._sizers.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(BoxLayout.prototype, "direction", {
	        /**
	         * Get the layout direction for the box layout.
	         */
	        get: function () {
	            return this._direction;
	        },
	        /**
	         * Set the layout direction for the box layout.
	         */
	        set: function (value) {
	            if (this._direction === value) {
	                return;
	            }
	            this._direction = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['direction'] = value;
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxLayout.prototype, "alignment", {
	        /**
	         * Get the content alignment for the box layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        get: function () {
	            return this._alignment;
	        },
	        /**
	         * Set the content alignment for the box layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        set: function (value) {
	            if (this._alignment === value) {
	                return;
	            }
	            this._alignment = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['alignment'] = value;
	            this.parent.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxLayout.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the box layout.
	         */
	        get: function () {
	            return this._spacing;
	        },
	        /**
	         * Set the inter-element spacing for the box layout.
	         */
	        set: function (value) {
	            value = Private.clampSpacing(value);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    BoxLayout.prototype.init = function () {
	        this.parent.dataset['direction'] = this.direction;
	        this.parent.dataset['alignment'] = this.alignment;
	        _super.prototype.init.call(this);
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.attachWidget = function (index, widget) {
	        // Create and add a new layout item for the widget.
	        algorithm_1.ArrayExt.insert(this._items, index, new layout_1.LayoutItem(widget));
	        // Create and add a new sizer for the widget.
	        algorithm_1.ArrayExt.insert(this._sizers, index, new boxengine_1.BoxSizer());
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Move the layout item for the widget.
	        algorithm_1.ArrayExt.move(this._items, fromIndex, toIndex);
	        // Move the sizer for the widget.
	        algorithm_1.ArrayExt.move(this._sizers, fromIndex, toIndex);
	        // Post an update request for the parent widget.
	        this.parent.update();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.detachWidget = function (index, widget) {
	        // Remove the layout item for the widget.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Remove the sizer for the widget.
	        algorithm_1.ArrayExt.removeAt(this._sizers, index);
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Dispose of the layout item.
	        item.dispose();
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    BoxLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    BoxLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    BoxLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    BoxLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    BoxLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    BoxLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    BoxLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    BoxLayout.prototype._fit = function () {
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Update the fixed space for the visible items.
	        this._fixed = this._spacing * Math.max(0, nVisible - 1);
	        // Setup the computed minimum size.
	        var horz = Private.isHorizontal(this._direction);
	        var minW = horz ? this._fixed : 0;
	        var minH = horz ? 0 : this._fixed;
	        // Update the sizers and computed minimum size.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item and corresponding box sizer.
	            var item = this._items[i];
	            var sizer = this._sizers[i];
	            // If the item is hidden, it should consume zero size.
	            if (item.isHidden) {
	                sizer.minSize = 0;
	                sizer.maxSize = 0;
	                continue;
	            }
	            // Update the size limits for the item.
	            item.fit();
	            // Update the size basis and stretch factor.
	            sizer.sizeHint = BoxLayout.getSizeBasis(item.widget);
	            sizer.stretch = BoxLayout.getStretch(item.widget);
	            // Update the sizer limits and computed min size.
	            if (horz) {
	                sizer.minSize = item.minWidth;
	                sizer.maxSize = item.maxWidth;
	                minW += item.minWidth;
	                minH = Math.max(minH, item.minHeight);
	            }
	            else {
	                sizer.minSize = item.minHeight;
	                sizer.maxSize = item.maxHeight;
	                minH += item.minHeight;
	                minW = Math.max(minW, item.minWidth);
	            }
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    BoxLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Bail early if there are no visible items to layout.
	        if (nVisible === 0) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the layout area adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Distribute the layout space and adjust the start position.
	        var delta;
	        switch (this._direction) {
	            case 'left-to-right':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, width - this._fixed));
	                break;
	            case 'top-to-bottom':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, height - this._fixed));
	                break;
	            case 'right-to-left':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, width - this._fixed));
	                left += width;
	                break;
	            case 'bottom-to-top':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, height - this._fixed));
	                top += height;
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Setup the variables for justification and alignment offset.
	        var extra = 0;
	        var offset = 0;
	        // Account for alignment if there is extra layout space.
	        if (delta > 0) {
	            switch (this._alignment) {
	                case 'start':
	                    break;
	                case 'center':
	                    extra = 0;
	                    offset = delta / 2;
	                    break;
	                case 'end':
	                    extra = 0;
	                    offset = delta;
	                    break;
	                case 'justify':
	                    extra = delta / nVisible;
	                    offset = 0;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Layout the items using the computed box sizes.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Fetch the computed size for the widget.
	            var size = this._sizers[i].size;
	            // Update the widget geometry and advance the relevant edge.
	            switch (this._direction) {
	                case 'left-to-right':
	                    item.update(left + offset, top, size + extra, height);
	                    left += size + extra + this._spacing;
	                    break;
	                case 'top-to-bottom':
	                    item.update(left, top + offset, width, size + extra);
	                    top += size + extra + this._spacing;
	                    break;
	                case 'right-to-left':
	                    item.update(left - offset - size - extra, top, size + extra, height);
	                    left -= size + extra + this._spacing;
	                    break;
	                case 'bottom-to-top':
	                    item.update(left, top - offset - size - extra, width, size + extra);
	                    top -= size + extra + this._spacing;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	    };
	    return BoxLayout;
	}(panellayout_1.PanelLayout));
	exports.BoxLayout = BoxLayout;
	/**
	 * The namespace for the `BoxLayout` class statics.
	 */
	(function (BoxLayout) {
	    /**
	     * Get the box layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box layout stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return Private.stretchProperty.get(widget);
	    }
	    BoxLayout.getStretch = getStretch;
	    /**
	     * Set the box layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        Private.stretchProperty.set(widget, value);
	    }
	    BoxLayout.setStretch = setStretch;
	    /**
	     * Get the box layout size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box layout size basis for the widget.
	     */
	    function getSizeBasis(widget) {
	        return Private.sizeBasisProperty.get(widget);
	    }
	    BoxLayout.getSizeBasis = getSizeBasis;
	    /**
	     * Set the box layout size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the size basis.
	     */
	    function setSizeBasis(widget, value) {
	        Private.sizeBasisProperty.set(widget, value);
	    }
	    BoxLayout.setSizeBasis = setSizeBasis;
	})(BoxLayout = exports.BoxLayout || (exports.BoxLayout = {}));
	exports.BoxLayout = BoxLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The property descriptor for a widget stretch factor.
	     */
	    Private.stretchProperty = new properties_1.AttachedProperty({
	        name: 'stretch',
	        create: function () { return 0; },
	        coerce: function (owner, value) { return Math.max(0, Math.floor(value)); },
	        changed: onChildSizingChanged
	    });
	    /**
	     * The property descriptor for a widget size basis.
	     */
	    Private.sizeBasisProperty = new properties_1.AttachedProperty({
	        name: 'sizeBasis',
	        create: function () { return 0; },
	        coerce: function (owner, value) { return Math.max(0, Math.floor(value)); },
	        changed: onChildSizingChanged
	    });
	    /**
	     * Test whether a direction has horizontal orientation.
	     */
	    function isHorizontal(dir) {
	        return dir === 'left-to-right' || dir === 'right-to-left';
	    }
	    Private.isHorizontal = isHorizontal;
	    /**
	     * Clamp a spacing value to an integer >= 0.
	     */
	    function clampSpacing(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampSpacing = clampSpacing;
	    /**
	     * The change handler for the attached sizing properties.
	     */
	    function onChildSizingChanged(child) {
	        if (child.parent && child.parent.layout instanceof BoxLayout) {
	            child.parent.fit();
	        }
	    }
	})(Private || (Private = {}));


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

	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__webpack_require__(176));
	__export(__webpack_require__(177));
	__export(__webpack_require__(179));
	__export(__webpack_require__(180));
	__export(__webpack_require__(181));
	__export(__webpack_require__(178));
	__export(__webpack_require__(182));
	__export(__webpack_require__(183));
	__export(__webpack_require__(184));
	__export(__webpack_require__(185));
	__export(__webpack_require__(186));
	__export(__webpack_require__(187));
	__export(__webpack_require__(188));
	__export(__webpack_require__(189));
	__export(__webpack_require__(190));
	__export(__webpack_require__(191));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for array-specific algorithms.
	 */
	var ArrayExt;
	(function (ArrayExt) {
	    /**
	     * Find the index of the first occurrence of a value in an array.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param value - The value to locate in the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first occurrence of the value, or `-1`
	     *   if the value is not found.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = ['one', 'two', 'three', 'four', 'one'];
	     * ArrayExt.firstIndexOf(data, 'red');        // -1
	     * ArrayExt.firstIndexOf(data, 'one');        // 0
	     * ArrayExt.firstIndexOf(data, 'one', 1);     // 4
	     * ArrayExt.firstIndexOf(data, 'two', 2);     // -1
	     * ArrayExt.firstIndexOf(data, 'two', 2, 1);  // 1
	     * ```
	     */
	    function firstIndexOf(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (stop < start) {
	            span = (stop + 1) + (n - start);
	        }
	        else {
	            span = stop - start + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            var j = (start + i) % n;
	            if (array[j] === value) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.firstIndexOf = firstIndexOf;
	    /**
	     * Find the index of the last occurrence of a value in an array.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param value - The value to locate in the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the last occurrence of the value, or `-1`
	     *   if the value is not found.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the front of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = ['one', 'two', 'three', 'four', 'one'];
	     * ArrayExt.lastIndexOf(data, 'red');        // -1
	     * ArrayExt.lastIndexOf(data, 'one');        // 4
	     * ArrayExt.lastIndexOf(data, 'one', 1);     // 0
	     * ArrayExt.lastIndexOf(data, 'two', 0);     // -1
	     * ArrayExt.lastIndexOf(data, 'two', 0, 1);  // 1
	     * ```
	     */
	    function lastIndexOf(array, value, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (start < stop) {
	            span = (start + 1) + (n - stop);
	        }
	        else {
	            span = start - stop + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            var j = (start - i + n) % n;
	            if (array[j] === value) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.lastIndexOf = lastIndexOf;
	    /**
	     * Find the index of the first value which matches a predicate.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first matching value, or `-1` if no
	     *   matching value is found.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findFirstIndex(data, isEven);       // 1
	     * ArrayExt.findFirstIndex(data, isEven, 4);    // 5
	     * ArrayExt.findFirstIndex(data, isEven, 6);    // -1
	     * ArrayExt.findFirstIndex(data, isEven, 6, 5); // 1
	     * ```
	     */
	    function findFirstIndex(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (stop < start) {
	            span = (stop + 1) + (n - start);
	        }
	        else {
	            span = stop - start + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            var j = (start + i) % n;
	            if (fn(array[j], j)) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.findFirstIndex = findFirstIndex;
	    /**
	     * Find the index of the last value which matches a predicate.
	     *
	     * @param object - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the last matching value, or `-1` if no
	     *   matching value is found.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the front of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findLastIndex(data, isEven);        // 5
	     * ArrayExt.findLastIndex(data, isEven, 4);     // 3
	     * ArrayExt.findLastIndex(data, isEven, 0);     // -1
	     * ArrayExt.findLastIndex(data, isEven, 0, 1);  // 5
	     * ```
	     */
	    function findLastIndex(array, fn, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var d;
	        if (start < stop) {
	            d = (start + 1) + (n - stop);
	        }
	        else {
	            d = start - stop + 1;
	        }
	        for (var i = 0; i < d; ++i) {
	            var j = (start - i + n) % n;
	            if (fn(array[j], j)) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.findLastIndex = findLastIndex;
	    /**
	     * Find the first value which matches a predicate.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The first matching value, or `undefined` if no matching
	     *   value is found.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findFirstValue(data, isEven);       // 2
	     * ArrayExt.findFirstValue(data, isEven, 2);    // 4
	     * ArrayExt.findFirstValue(data, isEven, 6);    // undefined
	     * ArrayExt.findFirstValue(data, isEven, 6, 5); // 2
	     * ```
	     */
	    function findFirstValue(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var index = findFirstIndex(array, fn, start, stop);
	        return index !== -1 ? array[index] : undefined;
	    }
	    ArrayExt.findFirstValue = findFirstValue;
	    /**
	     * Find the last value which matches a predicate.
	     *
	     * @param object - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The last matching value, or `undefined` if no matching
	     *   value is found.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the front of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findLastValue(data, isEven);        // 2
	     * ArrayExt.findLastValue(data, isEven, 4);     // 4
	     * ArrayExt.findLastValue(data, isEven, 0);     // undefined
	     * ArrayExt.findLastValue(data, isEven, 0, 1);  // 2
	     * ```
	     */
	    function findLastValue(array, fn, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var index = findLastIndex(array, fn, start, stop);
	        return index !== -1 ? array[index] : undefined;
	    }
	    ArrayExt.findLastValue = findLastValue;
	    /**
	     * Find the index of the first element which compares `>=` to a value.
	     *
	     * @param array - The sorted array-like object to search.
	     *
	     * @param value - The value to locate in the array.
	     *
	     * @param fn - The 3-way comparison function to apply to the values.
	     *   It should return `< 0` if an element is less than a value, `0` if
	     *   an element is equal to a value, or `> 0` if an element is greater
	     *   than a value.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first element which compares `>=` to the
	     *   value, or `length` if there is no such element. If the computed
	     *   index for `stop` is less than `start`, then the computed index
	     *   for `start` is returned.
	     *
	     * #### Notes
	     * The array must already be sorted in ascending order according to
	     * the comparison function.
	     *
	     * #### Complexity
	     * Logarithmic.
	     *
	     * #### Undefined Behavior
	     * Searching a range which is not sorted in ascending order.
	     *
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function numberCmp(a: number, b: number): number {
	     *   return a - b;
	     * }
	     *
	     * let data = [0, 3, 4, 7, 7, 9];
	     * ArrayExt.lowerBound(data, 0, numberCmp);   // 0
	     * ArrayExt.lowerBound(data, 6, numberCmp);   // 3
	     * ArrayExt.lowerBound(data, 7, numberCmp);   // 3
	     * ArrayExt.lowerBound(data, -1, numberCmp);  // 0
	     * ArrayExt.lowerBound(data, 10, numberCmp);  // 6
	     * ```
	     */
	    function lowerBound(array, value, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var begin = start;
	        var span = stop - start + 1;
	        while (span > 0) {
	            var half = span >> 1;
	            var middle = begin + half;
	            if (fn(array[middle], value) < 0) {
	                begin = middle + 1;
	                span -= half + 1;
	            }
	            else {
	                span = half;
	            }
	        }
	        return begin;
	    }
	    ArrayExt.lowerBound = lowerBound;
	    /**
	     * Find the index of the first element which compares `>` than a value.
	     *
	     * @param array - The sorted array-like object to search.
	     *
	     * @param value - The value to locate in the array.
	     *
	     * @param fn - The 3-way comparison function to apply to the values.
	     *   It should return `< 0` if an element is less than a value, `0` if
	     *   an element is equal to a value, or `> 0` if an element is greater
	     *   than a value.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first element which compares `>` than the
	     *   value, or `length` if there is no such element. If the computed
	     *   index for `stop` is less than `start`, then the computed index
	     *   for `start` is returned.
	     *
	     * #### Notes
	     * The array must already be sorted in ascending order according to
	     * the comparison function.
	     *
	     * #### Complexity
	     * Logarithmic.
	     *
	     * #### Undefined Behavior
	     * Searching a range which is not sorted in ascending order.
	     *
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function numberCmp(a: number, b: number): number {
	     *   return a - b;
	     * }
	     *
	     * let data = [0, 3, 4, 7, 7, 9];
	     * ArrayExt.upperBound(data, 0, numberCmp);   // 1
	     * ArrayExt.upperBound(data, 6, numberCmp);   // 3
	     * ArrayExt.upperBound(data, 7, numberCmp);   // 5
	     * ArrayExt.upperBound(data, -1, numberCmp);  // 0
	     * ArrayExt.upperBound(data, 10, numberCmp);  // 6
	     * ```
	     */
	    function upperBound(array, value, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var begin = start;
	        var span = stop - start + 1;
	        while (span > 0) {
	            var half = span >> 1;
	            var middle = begin + half;
	            if (fn(array[middle], value) > 0) {
	                span = half;
	            }
	            else {
	                begin = middle + 1;
	                span -= half + 1;
	            }
	        }
	        return begin;
	    }
	    ArrayExt.upperBound = upperBound;
	    /**
	     * Move an element in an array from one index to another.
	     *
	     * @param array - The mutable array-like object of interest.
	     *
	     * @param fromIndex - The index of the element to move. Negative
	     *   values are taken as an offset from the end of the array.
	     *
	     * @param toIndex - The target index of the element. Negative
	     *   values are taken as an offset from the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `fromIndex` or `toIndex` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2, 3, 4];
	     * ArrayExt.move(data, 1, 2);  // [0, 2, 1, 3, 4]
	     * ArrayExt.move(data, 4, 2);  // [0, 2, 4, 1, 3]
	     * ```
	     */
	    function move(array, fromIndex, toIndex) {
	        var n = array.length;
	        if (n <= 1) {
	            return;
	        }
	        if (fromIndex < 0) {
	            fromIndex = Math.max(0, fromIndex + n);
	        }
	        else {
	            fromIndex = Math.min(fromIndex, n - 1);
	        }
	        if (toIndex < 0) {
	            toIndex = Math.max(0, toIndex + n);
	        }
	        else {
	            toIndex = Math.min(toIndex, n - 1);
	        }
	        if (fromIndex === toIndex) {
	            return;
	        }
	        var value = array[fromIndex];
	        var d = fromIndex < toIndex ? 1 : -1;
	        for (var i = fromIndex; i !== toIndex; i += d) {
	            array[i] = array[i + d];
	        }
	        array[toIndex] = value;
	    }
	    ArrayExt.move = move;
	    /**
	     * Reverse an array in-place.
	     *
	     * @param array - The mutable array-like object of interest.
	     *
	     * @param start - The index of the first element in the range to be
	     *   reversed, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   reversed, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or  `stop` index which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2, 3, 4];
	     * ArrayExt.reverse(data, 1, 3);  // [0, 3, 2, 1, 4]
	     * ArrayExt.reverse(data, 3);     // [0, 3, 2, 4, 1]
	     * ArrayExt.reverse(data);        // [1, 4, 2, 3, 0]
	     * ```
	     */
	    function reverse(array, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n <= 1) {
	            return;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        while (start < stop) {
	            var a = array[start];
	            var b = array[stop];
	            array[start++] = b;
	            array[stop--] = a;
	        }
	    }
	    ArrayExt.reverse = reverse;
	    /**
	     * Rotate the elements of an array in-place.
	     *
	     * @param array - The mutable array-like object of interest.
	     *
	     * @param delta - The amount of rotation to apply to the elements. A
	     *   positive value will rotate the elements to the left. A negative
	     *   value will rotate the elements to the right.
	     *
	     * @param start - The index of the first element in the range to be
	     *   rotated, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   rotated, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `delta`, `start`, or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2, 3, 4];
	     * ArrayExt.rotate(data, 2);        // [2, 3, 4, 0, 1]
	     * ArrayExt.rotate(data, -2);       // [0, 1, 2, 3, 4]
	     * ArrayExt.rotate(data, 10);       // [0, 1, 2, 3, 4]
	     * ArrayExt.rotate(data, 9);        // [4, 0, 1, 2, 3]
	     * ArrayExt.rotate(data, 2, 1, 3);  // [4, 2, 0, 1, 3]
	     * ```
	     */
	    function rotate(array, delta, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n <= 1) {
	            return;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        if (start >= stop) {
	            return;
	        }
	        var length = stop - start + 1;
	        if (delta > 0) {
	            delta = delta % length;
	        }
	        else if (delta < 0) {
	            delta = ((delta % length) + length) % length;
	        }
	        if (delta === 0) {
	            return;
	        }
	        var pivot = start + delta;
	        reverse(array, start, pivot - 1);
	        reverse(array, pivot, stop);
	        reverse(array, start, stop);
	    }
	    ArrayExt.rotate = rotate;
	    /**
	     * Fill an array with a static value.
	     *
	     * @param array - The mutable array-like object to fill.
	     *
	     * @param value - The static value to use to fill the array.
	     *
	     * @param start - The index of the first element in the range to be
	     *   filled, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   filled, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * #### Notes
	     * If `stop < start` the fill will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = ['one', 'two', 'three', 'four'];
	     * ArrayExt.fill(data, 'r');        // ['r', 'r', 'r', 'r']
	     * ArrayExt.fill(data, 'g', 1);     // ['r', 'g', 'g', 'g']
	     * ArrayExt.fill(data, 'b', 2, 3);  // ['r', 'g', 'b', 'b']
	     * ArrayExt.fill(data, 'z', 3, 1);  // ['z', 'z', 'b', 'z']
	     * ```
	     */
	    function fill(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (stop < start) {
	            span = (stop + 1) + (n - start);
	        }
	        else {
	            span = stop - start + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            array[(start + i) % n] = value;
	        }
	    }
	    ArrayExt.fill = fill;
	    /**
	     * Insert a value into an array at a specific index.
	     *
	     * @param array - The array of interest.
	     *
	     * @param index - The index at which to insert the value. Negative
	     *   values are taken as an offset from the end of the array.
	     *
	     * @param value - The value to set at the specified index.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2];
	     * ArrayExt.insert(data, 0, -1);  // [-1, 0, 1, 2]
	     * ArrayExt.insert(data, 2, 12);  // [-1, 0, 12, 1, 2]
	     * ArrayExt.insert(data, -1, 7);  // [-1, 0, 12, 1, 7, 2]
	     * ArrayExt.insert(data, 6, 19);  // [-1, 0, 12, 1, 7, 2, 19]
	     * ```
	     */
	    function insert(array, index, value) {
	        var n = array.length;
	        if (index < 0) {
	            index = Math.max(0, index + n);
	        }
	        else {
	            index = Math.min(index, n);
	        }
	        for (var i = n; i > index; --i) {
	            array[i] = array[i - 1];
	        }
	        array[index] = value;
	    }
	    ArrayExt.insert = insert;
	    /**
	     * Remove and return a value at a specific index in an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param index - The index of the value to remove. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The value at the specified index, or `undefined` if the
	     *   index is out of range.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeAt(data, 2);   // 23
	     * ArrayExt.removeAt(data, -2);  // 12
	     * ArrayExt.removeAt(data, 10);  // undefined;
	     * ```
	     */
	    function removeAt(array, index) {
	        var n = array.length;
	        if (index < 0) {
	            index += n;
	        }
	        if (index < 0 || index >= n) {
	            return undefined;
	        }
	        var value = array[index];
	        for (var i = index + 1; i < n; ++i) {
	            array[i - 1] = array[i];
	        }
	        array.length = n - 1;
	        return value;
	    }
	    ArrayExt.removeAt = removeAt;
	    /**
	     * Remove the first occurrence of a value from an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param value - The value to remove from the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the removed value, or `-1` if the value
	     *   is not contained in the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeFirstOf(data, 12);        // 1
	     * ArrayExt.removeFirstOf(data, 17);        // -1
	     * ArrayExt.removeFirstOf(data, 39, 3);     // -1
	     * ArrayExt.removeFirstOf(data, 39, 3, 2);  // 2
	     * ```
	     */
	    function removeFirstOf(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var index = firstIndexOf(array, value, start, stop);
	        if (index !== -1) {
	            removeAt(array, index);
	        }
	        return index;
	    }
	    ArrayExt.removeFirstOf = removeFirstOf;
	    /**
	     * Remove the last occurrence of a value from an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param value - The value to remove from the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the removed value, or `-1` if the value
	     *   is not contained in the array.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeLastOf(data, 12);        // 5
	     * ArrayExt.removeLastOf(data, 17);        // -1
	     * ArrayExt.removeLastOf(data, 39, 2);     // -1
	     * ArrayExt.removeLastOf(data, 39, 2, 3);  // 3
	     * ```
	     */
	    function removeLastOf(array, value, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var index = lastIndexOf(array, value, start, stop);
	        if (index !== -1) {
	            removeAt(array, index);
	        }
	        return index;
	    }
	    ArrayExt.removeLastOf = removeLastOf;
	    /**
	     * Remove all occurrences of a value from an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param value - The value to remove from the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The number of elements removed from the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will conceptually wrap at the end of
	     * the array, however the array will be traversed front-to-back.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [14, 12, 23, 39, 14, 12, 19, 14];
	     * ArrayExt.removeAllOf(data, 12);        // 2
	     * ArrayExt.removeAllOf(data, 17);        // 0
	     * ArrayExt.removeAllOf(data, 14, 1, 4);  // 1
	     * ```
	     */
	    function removeAllOf(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var count = 0;
	        for (var i = 0; i < n; ++i) {
	            if (start <= stop && (i >= start && i <= stop) && array[i] === value) {
	                count++;
	            }
	            else if (stop < start && (i <= stop || i >= start) && array[i] === value) {
	                count++;
	            }
	            else if (count > 0) {
	                array[i - count] = array[i];
	            }
	        }
	        if (count > 0) {
	            array.length = n - count;
	        }
	        return count;
	    }
	    ArrayExt.removeAllOf = removeAllOf;
	    /**
	     * Remove the first occurrence of a value which matches a predicate.
	     *
	     * @param array - The array of interest.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The removed `{ index, value }`, which will be `-1` and
	     *   `undefined` if the value is not contained in the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeFirstWhere(data, isEven);     // { index: 0, value: 0 }
	     * ArrayExt.removeFirstWhere(data, isEven, 2);  // { index: 3, value: 14 }
	     * ArrayExt.removeFirstWhere(data, isEven, 4);  // { index: -1, value: undefined }
	     * ```
	     */
	    function removeFirstWhere(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var value;
	        var index = findFirstIndex(array, fn, start, stop);
	        if (index !== -1) {
	            value = removeAt(array, index);
	        }
	        return { index: index, value: value };
	    }
	    ArrayExt.removeFirstWhere = removeFirstWhere;
	    /**
	     * Remove the last occurrence of a value which matches a predicate.
	     *
	     * @param array - The array of interest.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The removed `{ index, value }`, which will be `-1` and
	     *   `undefined` if the value is not contained in the array.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeLastWhere(data, isEven);        // { index: 5, value: 12 }
	     * ArrayExt.removeLastWhere(data, isEven, 2);     // { index: 1, value: 12 }
	     * ArrayExt.removeLastWhere(data, isEven, 2, 1);  // { index: -1, value: undefined }
	     * ```
	     */
	    function removeLastWhere(array, fn, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var value;
	        var index = findLastIndex(array, fn, start, stop);
	        if (index !== -1) {
	            value = removeAt(array, index);
	        }
	        return { index: index, value: value };
	    }
	    ArrayExt.removeLastWhere = removeLastWhere;
	    /**
	     * Remove all occurrences of values which match a predicate.
	     *
	     * @param array - The array of interest.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The number of elements removed from the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will conceptually wrap at the end of
	     * the array, however the array will be traversed front-to-back.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * function isNegative(value: number): boolean {
	     *   return value < 0;
	     * }
	     *
	     * let data = [0, 12, -13, -9, 23, 39, 14, -15, 12, 75];
	     * ArrayExt.removeAllWhere(data, isEven);            // 4
	     * ArrayExt.removeAllWhere(data, isNegative, 0, 3);  // 2
	     * ```
	     */
	    function removeAllWhere(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var count = 0;
	        for (var i = 0; i < n; ++i) {
	            if (start <= stop && (i >= start && i <= stop) && fn(array[i], i)) {
	                count++;
	            }
	            else if (stop < start && (i <= stop || i >= start) && fn(array[i], i)) {
	                count++;
	            }
	            else if (count > 0) {
	                array[i - count] = array[i];
	            }
	        }
	        if (count > 0) {
	            array.length = n - count;
	        }
	        return count;
	    }
	    ArrayExt.removeAllWhere = removeAllWhere;
	})(ArrayExt = exports.ArrayExt || (exports.ArrayExt = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Chain together several iterables.
	 *
	 * @param objects - The iterable or array-like objects of interest.
	 *
	 * @returns An iterator which yields the values of the iterables
	 *   in the order in which they are supplied.
	 *
	 * #### Example
	 * ```typescript
	 * import { chain, toArray } from '@phosphor/algorithm';
	 *
	 * let data1 = [1, 2, 3];
	 * let data2 = [4, 5, 6];
	 *
	 * let stream = chain(data1, data2);
	 *
	 * toArray(stream);  // [1, 2, 3, 4, 5, 6]
	 * ```
	 */
	function chain() {
	    var objects = [];
	    for (var _i = 0; _i < arguments.length; _i++) {
	        objects[_i] = arguments[_i];
	    }
	    return new ChainIterator(iter_1.iter(objects.map(iter_1.iter)));
	}
	exports.chain = chain;
	/**
	 * An iterator which chains together several iterators.
	 */
	var ChainIterator = (function () {
	    /**
	     * Construct a new chain iterator.
	     *
	     * @param source - The iterator of iterators of interest.
	     */
	    function ChainIterator(source) {
	        this._cloned = false;
	        this._source = source;
	        this._active = undefined;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    ChainIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    ChainIterator.prototype.clone = function () {
	        var result = new ChainIterator(this._source.clone());
	        result._active = this._active && this._active.clone();
	        result._cloned = true;
	        this._cloned = true;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    ChainIterator.prototype.next = function () {
	        if (this._active === undefined) {
	            var active = this._source.next();
	            if (active === undefined) {
	                return undefined;
	            }
	            this._active = this._cloned ? active.clone() : active;
	        }
	        var value = this._active.next();
	        if (value !== undefined) {
	            return value;
	        }
	        this._active = undefined;
	        return this.next();
	    };
	    return ChainIterator;
	}());
	exports.ChainIterator = ChainIterator;


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator for an iterable object.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @returns A new iterator for the given object.
	 *
	 * #### Notes
	 * This function allows iteration algorithms to operate on user-defined
	 * iterable types and builtin array-like objects in a uniform fashion.
	 */
	function iter(object) {
	    var it;
	    if (typeof object.iter === 'function') {
	        it = object.iter();
	    }
	    else {
	        it = new ArrayIterator(object);
	    }
	    return it;
	}
	exports.iter = iter;
	/**
	 * Invoke a function for each value in an iterable.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The callback function to invoke for each value.
	 *
	 * #### Notes
	 * Iteration can be terminated early by returning `false` from the
	 * callback function.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { each } from '@phosphor/algorithm';
	 *
	 * let data = [5, 7, 0, -2, 9];
	 *
	 * each(data, value => { console.log(value); });
	 * ```
	 */
	function each(object, fn) {
	    var index = 0;
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, index++) === false) {
	            return;
	        }
	    }
	}
	exports.each = each;
	/**
	 * Test whether all values in an iterable satisfy a predicate.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The predicate function to invoke for each value.
	 *
	 * @returns `true` if all values pass the test, `false` otherwise.
	 *
	 * #### Notes
	 * Iteration terminates on the first `false` predicate result.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { every } from '@phosphor/algorithm';
	 *
	 * let data = [5, 7, 1];
	 *
	 * every(data, value => value % 2 === 0);  // false
	 * every(data, value => value % 2 === 1);  // true
	 * ```
	 */
	function every(object, fn) {
	    var index = 0;
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (!fn(value, index++)) {
	            return false;
	        }
	    }
	    return true;
	}
	exports.every = every;
	/**
	 * Test whether any value in an iterable satisfies a predicate.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The predicate function to invoke for each value.
	 *
	 * @returns `true` if any value passes the test, `false` otherwise.
	 *
	 * #### Notes
	 * Iteration terminates on the first `true` predicate result.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { some } from '@phosphor/algorithm';
	 *
	 * let data = [5, 7, 1];
	 *
	 * some(data, value => value === 7);  // true
	 * some(data, value => value === 3);  // false
	 * ```
	 */
	function some(object, fn) {
	    var index = 0;
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, index++)) {
	            return true;
	        }
	    }
	    return false;
	}
	exports.some = some;
	/**
	 * Create an array from an iterable of values.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @returns A new array of values from the given object.
	 *
	 * #### Example
	 * ```typescript
	 * import { iter, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = iter(data);
	 *
	 * toArray(stream);  // [1, 2, 3, 4, 5, 6];
	 * ```
	 */
	function toArray(object) {
	    var index = 0;
	    var result = [];
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        result[index++] = value;
	    }
	    return result;
	}
	exports.toArray = toArray;
	/**
	 * An iterator for an array-like object.
	 *
	 * #### Notes
	 * This iterator can be used for any builtin JS array-like object.
	 */
	var ArrayIterator = (function () {
	    /**
	     * Construct a new array iterator.
	     *
	     * @param source - The array-like object of interest.
	     */
	    function ArrayIterator(source) {
	        this._index = 0;
	        this._source = source;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    ArrayIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    ArrayIterator.prototype.clone = function () {
	        var result = new ArrayIterator(this._source);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    ArrayIterator.prototype.next = function () {
	        if (this._index >= this._source.length) {
	            return undefined;
	        }
	        return this._source[this._index++];
	    };
	    return ArrayIterator;
	}());
	exports.ArrayIterator = ArrayIterator;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an empty iterator.
	 *
	 * @returns A new iterator which yields nothing.
	 *
	 * #### Example
	 * ```typescript
	 * import { empty, toArray } from '@phosphor/algorithm';
	 *
	 * let stream = empty<number>();
	 *
	 * toArray(stream);  // []
	 * ```
	 */
	function empty() {
	    return new EmptyIterator();
	}
	exports.empty = empty;
	/**
	 * An iterator which is always empty.
	 */
	var EmptyIterator = (function () {
	    /**
	     * Construct a new empty iterator.
	     */
	    function EmptyIterator() {
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    EmptyIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    EmptyIterator.prototype.clone = function () {
	        return new EmptyIterator();
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    EmptyIterator.prototype.next = function () {
	        return undefined;
	    };
	    return EmptyIterator;
	}());
	exports.EmptyIterator = EmptyIterator;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Filter an iterable for values which pass a test.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The predicate function to invoke for each value.
	 *
	 * @returns An iterator which yields the values which pass the test.
	 *
	 * #### Example
	 * ```typescript
	 * import { filter, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = filter(data, value => value % 2 === 0);
	 *
	 * toArray(stream);  // [2, 4, 6]
	 * ```
	 */
	function filter(object, fn) {
	    return new FilterIterator(iter_1.iter(object), fn);
	}
	exports.filter = filter;
	/**
	 * An iterator which yields values which pass a test.
	 */
	var FilterIterator = (function () {
	    /**
	     * Construct a new filter iterator.
	     *
	     * @param source - The iterator of values of interest.
	     *
	     * @param fn - The predicate function to invoke for each value.
	     */
	    function FilterIterator(source, fn) {
	        this._index = 0;
	        this._source = source;
	        this._fn = fn;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    FilterIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    FilterIterator.prototype.clone = function () {
	        var result = new FilterIterator(this._source.clone(), this._fn);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    FilterIterator.prototype.next = function () {
	        var fn = this._fn;
	        var it = this._source;
	        var value;
	        while ((value = it.next()) !== undefined) {
	            if (fn(value, this._index++)) {
	                return value;
	            }
	        }
	        return undefined;
	    };
	    return FilterIterator;
	}());
	exports.FilterIterator = FilterIterator;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Find the first value in an iterable which matches a predicate.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The predicate function to apply to the values.
	 *
	 * @returns The first matching value, or `undefined` if no matching
	 *   value is found.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { find } from '@phosphor/algorithm';
	 *
	 * interface IAnimal { species: string, name: string };
	 *
	 * function isCat(value: IAnimal): boolean {
	 *   return value.species === 'cat';
	 * }
	 *
	 * let data: IAnimal[] = [
	 *   { species: 'dog', name: 'spot' },
	 *   { species: 'cat', name: 'fluffy' },
	 *   { species: 'alligator', name: 'pocho' }
	 * ];
	 *
	 * find(data, isCat).name;  // 'fluffy'
	 * ```
	 */
	function find(object, fn) {
	    var index = 0;
	    var it = iter_1.iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, index++)) {
	            return value;
	        }
	    }
	    return undefined;
	}
	exports.find = find;
	/**
	 * Find the minimum value in an iterable.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The 3-way comparison function to apply to the values.
	 *   It should return `< 0` if the first value is less than the second.
	 *   `0` if the values are equivalent, or `> 0` if the first value is
	 *   greater than the second.
	 *
	 * @returns The minimum value in the iterable. If multiple values are
	 *   equivalent to the minimum, the left-most value is returned. If
	 *   the iterable is empty, this returns `undefined`.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { min } from '@phosphor/algorithm';
	 *
	 * function numberCmp(a: number, b: number): number {
	 *   return a - b;
	 * }
	 *
	 * min([7, 4, 0, 3, 9, 4], numberCmp);  // 0
	 * ```
	 */
	function min(object, fn) {
	    var it = iter_1.iter(object);
	    var value = it.next();
	    if (value === undefined) {
	        return undefined;
	    }
	    var result = value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, result) < 0) {
	            result = value;
	        }
	    }
	    return result;
	}
	exports.min = min;
	/**
	 * Find the maximum value in an iterable.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The 3-way comparison function to apply to the values.
	 *   It should return `< 0` if the first value is less than the second.
	 *   `0` if the values are equivalent, or `> 0` if the first value is
	 *   greater than the second.
	 *
	 * @returns The maximum value in the iterable. If multiple values are
	 *   equivalent to the maximum, the left-most value is returned. If
	 *   the iterable is empty, this returns `undefined`.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { max } from '@phosphor/algorithm';
	 *
	 * function numberCmp(a: number, b: number): number {
	 *   return a - b;
	 * }
	 *
	 * max([7, 4, 0, 3, 9, 4], numberCmp);  // 9
	 * ```
	 */
	function max(object, fn) {
	    var it = iter_1.iter(object);
	    var value = it.next();
	    if (value === undefined) {
	        return undefined;
	    }
	    var result = value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, result) > 0) {
	            result = value;
	        }
	    }
	    return result;
	}
	exports.max = max;
	/**
	 * Find the minimum and maximum values in an iterable.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The 3-way comparison function to apply to the values.
	 *   It should return `< 0` if the first value is less than the second.
	 *   `0` if the values are equivalent, or `> 0` if the first value is
	 *   greater than the second.
	 *
	 * @returns A 2-tuple of the `[min, max]` values in the iterable. If
	 *   multiple values are equivalent, the left-most values are returned.
	 *   If the iterable is empty, this returns `undefined`.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { minmax } from '@phosphor/algorithm';
	 *
	 * function numberCmp(a: number, b: number): number {
	 *   return a - b;
	 * }
	 *
	 * minmax([7, 4, 0, 3, 9, 4], numberCmp);  // [0, 9]
	 * ```
	 */
	function minmax(object, fn) {
	    var it = iter_1.iter(object);
	    var value = it.next();
	    if (value === undefined) {
	        return undefined;
	    }
	    var vmin = value;
	    var vmax = value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, vmin) < 0) {
	            vmin = value;
	        }
	        else if (fn(value, vmax) > 0) {
	            vmax = value;
	        }
	    }
	    return [vmin, vmax];
	}
	exports.minmax = minmax;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Transform the values of an iterable with a mapping function.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The mapping function to invoke for each value.
	 *
	 * @returns An iterator which yields the transformed values.
	 *
	 * #### Example
	 * ```typescript
	 * import { map, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3];
	 *
	 * let stream = map(data, value => value * 2);
	 *
	 * toArray(stream);  // [2, 4, 6]
	 * ```
	 */
	function map(object, fn) {
	    return new MapIterator(iter_1.iter(object), fn);
	}
	exports.map = map;
	/**
	 * An iterator which transforms values using a mapping function.
	 */
	var MapIterator = (function () {
	    /**
	     * Construct a new map iterator.
	     *
	     * @param source - The iterator of values of interest.
	     *
	     * @param fn - The mapping function to invoke for each value.
	     */
	    function MapIterator(source, fn) {
	        this._index = 0;
	        this._source = source;
	        this._fn = fn;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    MapIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    MapIterator.prototype.clone = function () {
	        var result = new MapIterator(this._source.clone(), this._fn);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    MapIterator.prototype.next = function () {
	        var value = this._source.next();
	        if (value === undefined) {
	            return undefined;
	        }
	        return this._fn.call(undefined, value, this._index++);
	    };
	    return MapIterator;
	}());
	exports.MapIterator = MapIterator;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator of evenly spaced values.
	 *
	 * @param start - The starting value for the range, inclusive.
	 *
	 * @param stop - The stopping value for the range, exclusive.
	 *
	 * @param step - The distance between each value.
	 *
	 * @returns An iterator which produces evenly spaced values.
	 *
	 * #### Notes
	 * In the single argument form of `range(stop)`, `start` defaults to
	 * `0` and `step` defaults to `1`.
	 *
	 * In the two argument form of `range(start, stop)`, `step` defaults
	 * to `1`.
	 */
	function range(start, stop, step) {
	    if (stop === undefined) {
	        return new RangeIterator(0, start, 1);
	    }
	    if (step === undefined) {
	        return new RangeIterator(start, stop, 1);
	    }
	    return new RangeIterator(start, stop, step);
	}
	exports.range = range;
	/**
	 * An iterator which produces a range of evenly spaced values.
	 */
	var RangeIterator = (function () {
	    /**
	     * Construct a new range iterator.
	     *
	     * @param start - The starting value for the range, inclusive.
	     *
	     * @param stop - The stopping value for the range, exclusive.
	     *
	     * @param step - The distance between each value.
	     */
	    function RangeIterator(start, stop, step) {
	        this._index = 0;
	        this._start = start;
	        this._stop = stop;
	        this._step = step;
	        this._length = Private.rangeLength(start, stop, step);
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    RangeIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    RangeIterator.prototype.clone = function () {
	        var result = new RangeIterator(this._start, this._stop, this._step);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    RangeIterator.prototype.next = function () {
	        if (this._index >= this._length) {
	            return undefined;
	        }
	        return this._start + this._step * this._index++;
	    };
	    return RangeIterator;
	}());
	exports.RangeIterator = RangeIterator;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Compute the effective length of a range.
	     *
	     * @param start - The starting value for the range, inclusive.
	     *
	     * @param stop - The stopping value for the range, exclusive.
	     *
	     * @param step - The distance between each value.
	     *
	     * @returns The number of steps need to traverse the range.
	     */
	    function rangeLength(start, stop, step) {
	        if (step === 0) {
	            return Infinity;
	        }
	        if (start > stop && step > 0) {
	            return 0;
	        }
	        if (start < stop && step < 0) {
	            return 0;
	        }
	        return Math.ceil((stop - start) / step);
	    }
	    Private.rangeLength = rangeLength;
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	function reduce(object, fn, initial) {
	    // Setup the iterator and fetch the first value.
	    var index = 0;
	    var it = iter_1.iter(object);
	    var first = it.next();
	    // An empty iterator and no initial value is an error.
	    if (first === undefined && initial === undefined) {
	        throw new TypeError('Reduce of empty iterable with no initial value.');
	    }
	    // If the iterator is empty, return the initial value.
	    if (first === undefined) {
	        return initial;
	    }
	    // If the iterator has a single item and no initial value, the
	    // reducer is not invoked and the first item is the return value.
	    var second = it.next();
	    if (second === undefined && initial === undefined) {
	        return first;
	    }
	    // If iterator has a single item and an initial value is provided,
	    // the reducer is invoked and that result is the return value.
	    if (second === undefined) {
	        return fn(initial, first, index++);
	    }
	    // Setup the initial accumlated value.
	    var accumulator;
	    if (initial === undefined) {
	        accumulator = fn(first, second, index++);
	    }
	    else {
	        accumulator = fn(fn(initial, first, index++), second, index++);
	    }
	    // Iterate the rest of the values, updating the accumulator.
	    var next;
	    while ((next = it.next()) !== undefined) {
	        accumulator = fn(accumulator, next, index++);
	    }
	    // Return the final accumulated value.
	    return accumulator;
	}
	exports.reduce = reduce;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator which repeats a value a number of times.
	 *
	 * @param value - The value to repeat.
	 *
	 * @param count - The number of times to repeat the value.
	 *
	 * @returns A new iterator which repeats the specified value.
	 *
	 * #### Example
	 * ```typescript
	 * import { repeat, toArray } from '@phosphor/algorithm';
	 *
	 * let stream = repeat(7, 3);
	 *
	 * toArray(stream);  // [7, 7, 7]
	 * ```
	 */
	function repeat(value, count) {
	    return new RepeatIterator(value, count);
	}
	exports.repeat = repeat;
	/**
	 * Create an iterator which yields a value a single time.
	 *
	 * @param value - The value to wrap in an iterator.
	 *
	 * @returns A new iterator which yields the value a single time.
	 *
	 * #### Example
	 * ```typescript
	 * import { once, toArray } from '@phosphor/algorithm';
	 *
	 * let stream = once(7);
	 *
	 * toArray(stream);  // [7]
	 * ```
	 */
	function once(value) {
	    return new RepeatIterator(value, 1);
	}
	exports.once = once;
	/**
	 * An iterator which repeats a value a specified number of times.
	 */
	var RepeatIterator = (function () {
	    /**
	     * Construct a new repeat iterator.
	     *
	     * @param value - The value to repeat.
	     *
	     * @param count - The number of times to repeat the value.
	     */
	    function RepeatIterator(value, count) {
	        this._value = value;
	        this._count = count;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    RepeatIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    RepeatIterator.prototype.clone = function () {
	        return new RepeatIterator(this._value, this._count);
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    RepeatIterator.prototype.next = function () {
	        if (this._count <= 0) {
	            return undefined;
	        }
	        this._count--;
	        return this._value;
	    };
	    return RepeatIterator;
	}());
	exports.RepeatIterator = RepeatIterator;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator for a retroable object.
	 *
	 * @param object - The retroable or array-like object of interest.
	 *
	 * @returns An iterator which traverses the object's values in reverse.
	 *
	 * #### Example
	 * ```typescript
	 * import { retro, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = retro(data);
	 *
	 * toArray(stream);  // [6, 5, 4, 3, 2, 1]
	 * ```
	 */
	function retro(object) {
	    var it;
	    if (typeof object.retro === 'function') {
	        it = object.retro();
	    }
	    else {
	        it = new RetroArrayIterator(object);
	    }
	    return it;
	}
	exports.retro = retro;
	/**
	 * An iterator which traverses an array-like object in reverse.
	 *
	 * #### Notes
	 * This iterator can be used for any builtin JS array-like object.
	 */
	var RetroArrayIterator = (function () {
	    /**
	     * Construct a new retro iterator.
	     *
	     * @param source - The array-like object of interest.
	     */
	    function RetroArrayIterator(source) {
	        this._source = source;
	        this._index = source.length - 1;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    RetroArrayIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    RetroArrayIterator.prototype.clone = function () {
	        var result = new RetroArrayIterator(this._source);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    RetroArrayIterator.prototype.next = function () {
	        if (this._index < 0 || this._index >= this._source.length) {
	            return undefined;
	        }
	        return this._source[this._index--];
	    };
	    return RetroArrayIterator;
	}());
	exports.RetroArrayIterator = RetroArrayIterator;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Topologically sort an iterable of edges.
	 *
	 * @param edges - The iterable or array-like object of edges to sort.
	 *   An edge is represented as a 2-tuple of `[fromNode, toNode]`.
	 *
	 * @returns The topologically sorted array of nodes.
	 *
	 * #### Notes
	 * If a cycle is present in the graph, the cycle will be ignored and
	 * the return value will be only approximately sorted.
	 *
	 * #### Example
	 * ```typescript
	 * import { topologicSort } from '@phosphor/algorithm';
	 *
	 * let data = [
	 *   ['d', 'e'],
	 *   ['c', 'd'],
	 *   ['a', 'b'],
	 *   ['b', 'c']
	 * ];
	 *
	 * topologicSort(data);  // ['a', 'b', 'c', 'd', 'e']
	 */
	function topologicSort(edges) {
	    // Setup the shared sorting state.
	    var sorted = [];
	    var visited = new Set();
	    var graph = new Map();
	    // Add the edges to the graph.
	    iter_1.each(edges, addEdge);
	    // Visit each node in the graph.
	    graph.forEach(function (v, k) { visit(k); });
	    // Return the sorted results.
	    return sorted;
	    // Add an edge to the graph.
	    function addEdge(edge) {
	        var fromNode = edge[0], toNode = edge[1];
	        var children = graph.get(toNode);
	        if (children) {
	            children.push(fromNode);
	        }
	        else {
	            graph.set(toNode, [fromNode]);
	        }
	    }
	    // Recursively visit the node.
	    function visit(node) {
	        if (visited.has(node)) {
	            return;
	        }
	        visited.add(node);
	        var children = graph.get(node);
	        if (children) {
	            children.forEach(visit);
	        }
	        sorted.push(node);
	    }
	}
	exports.topologicSort = topologicSort;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Iterate over an iterable using a stepped increment.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param step - The distance to step on each iteration. A value
	 *   of less than `1` will behave the same as a value of `1`.
	 *
	 * @returns An iterator which traverses the iterable step-wise.
	 *
	 * #### Example
	 * ```typescript
	 * import { stride, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = stride(data, 2);
	 *
	 * toArray(stream);  // [1, 3, 5];
	 * ```
	 */
	function stride(object, step) {
	    return new StrideIterator(iter_1.iter(object), step);
	}
	exports.stride = stride;
	/**
	 * An iterator which traverses a source iterator step-wise.
	 */
	var StrideIterator = (function () {
	    /**
	     * Construct a new stride iterator.
	     *
	     * @param source - The iterator of values of interest.
	     *
	     * @param step - The distance to step on each iteration. A value
	     *   of less than `1` will behave the same as a value of `1`.
	     */
	    function StrideIterator(source, step) {
	        this._source = source;
	        this._step = step;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    StrideIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    StrideIterator.prototype.clone = function () {
	        return new StrideIterator(this._source.clone(), this._step);
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    StrideIterator.prototype.next = function () {
	        var value = this._source.next();
	        for (var n = this._step - 1; n > 0; --n) {
	            this._source.next();
	        }
	        return value;
	    };
	    return StrideIterator;
	}());
	exports.StrideIterator = StrideIterator;


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for string-specific algorithms.
	 */
	var StringExt;
	(function (StringExt) {
	    /**
	     * Find the indices of characters in a source text.
	     *
	     * @param source - The source text which should be searched.
	     *
	     * @param query - The characters to locate in the source text.
	     *
	     * @param start - The index to start the search.
	     *
	     * @returns The matched indices, or `null` if there is no match.
	     *
	     * #### Complexity
	     * Linear on `sourceText`.
	     *
	     * #### Notes
	     * In order for there to be a match, all of the characters in `query`
	     * **must** appear in `source` in the order given by `query`.
	     *
	     * Characters are matched using strict `===` equality.
	     */
	    function findIndices(source, query, start) {
	        if (start === void 0) { start = 0; }
	        var indices = new Array(query.length);
	        for (var i = 0, j = start, n = query.length; i < n; ++i, ++j) {
	            j = source.indexOf(query[i], j);
	            if (j === -1) {
	                return null;
	            }
	            indices[i] = j;
	        }
	        return indices;
	    }
	    StringExt.findIndices = findIndices;
	    /**
	     * A string matcher which uses a sum-of-squares algorithm.
	     *
	     * @param source - The source text which should be searched.
	     *
	     * @param query - The characters to locate in the source text.
	     *
	     * @param start - The index to start the search.
	     *
	     * @returns The match result, or `null` if there is no match.
	     *   A lower `score` represents a stronger match.
	     *
	     * #### Complexity
	     * Linear on `sourceText`.
	     *
	     * #### Notes
	     * This scoring algorithm uses a sum-of-squares approach to determine
	     * the score. In order for there to be a match, all of the characters
	     * in `query` **must** appear in `source` in order. The index of each
	     * matching character is squared and added to the score. This means
	     * that early and consecutive character matches are preferred, while
	     * late matches are heavily penalized.
	     */
	    function matchSumOfSquares(source, query, start) {
	        if (start === void 0) { start = 0; }
	        var indices = findIndices(source, query, start);
	        if (!indices) {
	            return null;
	        }
	        var score = 0;
	        for (var i = 0, n = indices.length; i < n; ++i) {
	            var j = indices[i] - start;
	            score += j * j;
	        }
	        return { score: score, indices: indices };
	    }
	    StringExt.matchSumOfSquares = matchSumOfSquares;
	    /**
	     * A string matcher which uses a sum-of-deltas algorithm.
	     *
	     * @param source - The source text which should be searched.
	     *
	     * @param query - The characters to locate in the source text.
	     *
	     * @param start - The index to start the search.
	     *
	     * @returns The match result, or `null` if there is no match.
	     *   A lower `score` represents a stronger match.
	     *
	     * #### Complexity
	     * Linear on `sourceText`.
	     *
	     * #### Notes
	     * This scoring algorithm uses a sum-of-deltas approach to determine
	     * the score. In order for there to be a match, all of the characters
	     * in `query` **must** appear in `source` in order. The delta between
	     * the indices are summed to create the score. This means that groups
	     * of matched characters are preferred, while fragmented matches are
	     * penalized.
	     */
	    function matchSumOfDeltas(source, query, start) {
	        if (start === void 0) { start = 0; }
	        var indices = findIndices(source, query, start);
	        if (!indices) {
	            return null;
	        }
	        var score = 0;
	        var last = start - 1;
	        for (var i = 0, n = indices.length; i < n; ++i) {
	            var j = indices[i];
	            score += j - last - 1;
	            last = j;
	        }
	        return { score: score, indices: indices };
	    }
	    StringExt.matchSumOfDeltas = matchSumOfDeltas;
	    /**
	     * Highlight the matched characters of a source text.
	     *
	     * @param source - The text which should be highlighted.
	     *
	     * @param indices - The indices of the matched characters. They must
	     *   appear in increasing order and must be in bounds of the source.
	     *
	     * @param fn - The function to apply to the matched chunks.
	     *
	     * @returns An array of unmatched and highlighted chunks.
	     */
	    function highlight(source, indices, fn) {
	        // Set up the result array.
	        var result = [];
	        // Set up the counter variables.
	        var k = 0;
	        var last = 0;
	        var n = indices.length;
	        // Iterator over each index.
	        while (k < n) {
	            // Set up the chunk indices.
	            var i = indices[k];
	            var j = indices[k];
	            // Advance the right chunk index until it's non-contiguous.
	            while (++k < n && indices[k] === j + 1) {
	                j++;
	            }
	            // Extract the unmatched text.
	            if (last < i) {
	                result.push(source.slice(last, i));
	            }
	            // Extract and highlight the matched text.
	            if (i < j + 1) {
	                result.push(fn(source.slice(i, j + 1)));
	            }
	            // Update the last visited index.
	            last = j + 1;
	        }
	        // Extract any remaining unmatched text.
	        if (last < source.length) {
	            result.push(source.slice(last));
	        }
	        // Return the highlighted result.
	        return result;
	    }
	    StringExt.highlight = highlight;
	})(StringExt = exports.StringExt || (exports.StringExt = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Take a fixed number of items from an iterable.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param count - The number of items to take from the iterable.
	 *
	 * @returns An iterator which yields the specified number of items
	 *   from the source iterable.
	 *
	 * #### Notes
	 * The returned iterator will exhaust early if the source iterable
	 * contains an insufficient number of items.
	 */
	function take(object, count) {
	    return new TakeIterator(iter_1.iter(object), count);
	}
	exports.take = take;
	/**
	 * An iterator which takes a fixed number of items from a source.
	 */
	var TakeIterator = (function () {
	    /**
	     * Construct a new take iterator.
	     *
	     * @param source - The iterator of interest.
	     *
	     * @param count - The number of items to take from the source.
	     */
	    function TakeIterator(source, count) {
	        this._source = source;
	        this._count = count;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    TakeIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    TakeIterator.prototype.clone = function () {
	        return new TakeIterator(this._source.clone(), this._count);
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    TakeIterator.prototype.next = function () {
	        if (this._count <= 0) {
	            return undefined;
	        }
	        var value = this._source.next();
	        if (value === undefined) {
	            return undefined;
	        }
	        this._count--;
	        return value;
	    };
	    return TakeIterator;
	}());
	exports.TakeIterator = TakeIterator;


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __webpack_require__(178);
	/**
	 * Iterate several iterables in lockstep.
	 *
	 * @param objects - The iterable or array-like objects of interest.
	 *
	 * @returns An iterator which yields successive tuples of values where
	 *   each value is taken in turn from the provided iterables. It will
	 *   be as long as the shortest provided iterable.
	 *
	 * #### Example
	 * ```typescript
	 * import { zip, toArray } from '@phosphor/algorithm';
	 *
	 * let data1 = [1, 2, 3];
	 * let data2 = [4, 5, 6];
	 *
	 * let stream = zip(data1, data2);
	 *
	 * toArray(stream);  // [[1, 4], [2, 5], [3, 6]]
	 * ```
	 */
	function zip() {
	    var objects = [];
	    for (var _i = 0; _i < arguments.length; _i++) {
	        objects[_i] = arguments[_i];
	    }
	    return new ZipIterator(objects.map(iter_1.iter));
	}
	exports.zip = zip;
	/**
	 * An iterator which iterates several sources in lockstep.
	 */
	var ZipIterator = (function () {
	    /**
	     * Construct a new zip iterator.
	     *
	     * @param source - The iterators of interest.
	     */
	    function ZipIterator(source) {
	        this._source = source;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    ZipIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    ZipIterator.prototype.clone = function () {
	        return new ZipIterator(this._source.map(function (it) { return it.clone(); }));
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    ZipIterator.prototype.next = function () {
	        var result = new Array(this._source.length);
	        for (var i = 0, n = this._source.length; i < n; ++i) {
	            var value = this._source[i].next();
	            if (value === undefined) {
	                return undefined;
	            }
	            result[i] = value;
	        }
	        return result;
	    };
	    return ZipIterator;
	}());
	exports.ZipIterator = ZipIterator;


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

	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__webpack_require__(193));
	__export(__webpack_require__(194));
	__export(__webpack_require__(195));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for element related utilities.
	 */
	var ElementExt;
	(function (ElementExt) {
	    /**
	     * Compute the box sizing for an element.
	     *
	     * @param element - The element of interest.
	     *
	     * @returns The box sizing data for the specified element.
	     */
	    function boxSizing(element) {
	        var style = window.getComputedStyle(element);
	        var bt = parseFloat(style.borderTopWidth) || 0;
	        var bl = parseFloat(style.borderLeftWidth) || 0;
	        var br = parseFloat(style.borderRightWidth) || 0;
	        var bb = parseFloat(style.borderBottomWidth) || 0;
	        var pt = parseFloat(style.paddingTop) || 0;
	        var pl = parseFloat(style.paddingLeft) || 0;
	        var pr = parseFloat(style.paddingRight) || 0;
	        var pb = parseFloat(style.paddingBottom) || 0;
	        var hs = bl + pl + pr + br;
	        var vs = bt + pt + pb + bb;
	        return {
	            borderTop: bt,
	            borderLeft: bl,
	            borderRight: br,
	            borderBottom: bb,
	            paddingTop: pt,
	            paddingLeft: pl,
	            paddingRight: pr,
	            paddingBottom: pb,
	            horizontalSum: hs,
	            verticalSum: vs
	        };
	    }
	    ElementExt.boxSizing = boxSizing;
	    /**
	     * Compute the size limits for an element.
	     *
	     * @param element - The element of interest.
	     *
	     * @returns The size limit data for the specified element.
	     */
	    function sizeLimits(element) {
	        var style = window.getComputedStyle(element);
	        var minWidth = parseFloat(style.minWidth) || 0;
	        var minHeight = parseFloat(style.minHeight) || 0;
	        var maxWidth = parseFloat(style.maxWidth) || Infinity;
	        var maxHeight = parseFloat(style.maxHeight) || Infinity;
	        maxWidth = Math.max(minWidth, maxWidth);
	        maxHeight = Math.max(minHeight, maxHeight);
	        return { minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight };
	    }
	    ElementExt.sizeLimits = sizeLimits;
	    /**
	     * Test whether a client position lies within an element.
	     *
	     * @param element - The DOM element of interest.
	     *
	     * @param clientX - The client X coordinate of interest.
	     *
	     * @param clientY - The client Y coordinate of interest.
	     *
	     * @returns Whether the point is within the given element.
	     */
	    function hitTest(element, clientX, clientY) {
	        var rect = element.getBoundingClientRect();
	        return (clientX >= rect.left &&
	            clientX < rect.right &&
	            clientY >= rect.top &&
	            clientY < rect.bottom);
	    }
	    ElementExt.hitTest = hitTest;
	    /**
	     * Vertically scroll an element into view if needed.
	     *
	     * @param area - The scroll area element.
	     *
	     * @param element - The element of interest.
	     *
	     * #### Notes
	     * This follows the "nearest" behavior of the native `scrollIntoView`
	     * method, which is not supported by all browsers.
	     * https://drafts.csswg.org/cssom-view/#element-scrolling-members
	     *
	     * If the element fully covers the visible area or is fully contained
	     * within the visible area, no scrolling will take place. Otherwise,
	     * the nearest edges of the area and element are aligned.
	     */
	    function scrollIntoViewIfNeeded(area, element) {
	        var ar = area.getBoundingClientRect();
	        var er = element.getBoundingClientRect();
	        if (er.top <= ar.top && er.bottom >= ar.bottom) {
	            return;
	        }
	        if (er.top < ar.top && er.height <= ar.height) {
	            area.scrollTop -= ar.top - er.top;
	            return;
	        }
	        if (er.bottom > ar.bottom && er.height >= ar.height) {
	            area.scrollTop -= ar.top - er.top;
	            return;
	        }
	        if (er.top < ar.top && er.height > ar.height) {
	            area.scrollTop -= ar.bottom - er.bottom;
	            return;
	        }
	        if (er.bottom > ar.bottom && er.height < ar.height) {
	            area.scrollTop -= ar.bottom - er.bottom;
	            return;
	        }
	    }
	    ElementExt.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
	})(ElementExt = exports.ElementExt || (exports.ElementExt = {}));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for platform related utilities.
	 */
	var Platform;
	(function (Platform) {
	    /**
	     * A flag indicating whether the platform is Mac.
	     */
	    Platform.IS_MAC = !!navigator.platform.match(/Mac/i);
	    /**
	     * A flag indicating whether the platform is Windows.
	     */
	    Platform.IS_WIN = !!navigator.platform.match(/Win/i);
	    /**
	     * A flag indicating whether the browser is IE.
	     */
	    Platform.IS_IE = /Trident/.test(navigator.userAgent);
	    /**
	     * A flag indicating whether the browser is Edge.
	     */
	    Platform.IS_EDGE = /Edge/.test(navigator.userAgent);
	})(Platform = exports.Platform || (exports.Platform = {}));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for selector related utilities.
	 */
	var Selector;
	(function (Selector) {
	    /**
	     * Calculate the specificity of a single CSS selector.
	     *
	     * @param selector - The CSS selector of interest.
	     *
	     * @returns The specificity of the selector.
	     *
	     * #### Undefined Behavior
	     * The selector is invalid.
	     *
	     * #### Notes
	     * This is based on https://www.w3.org/TR/css3-selectors/#specificity
	     *
	     * A larger number represents a more specific selector.
	     *
	     * The smallest possible specificity is `0`.
	     *
	     * The result is represented as a hex number `0x<aa><bb><cc>` where
	     * each component is the count of the respective selector clause.
	     *
	     * If the selector contains commas, only the first clause is used.
	     *
	     * The computed result is cached, so subsequent calculations for the
	     * same selector are extremely fast.
	     */
	    function calculateSpecificity(selector) {
	        if (selector in Private.specificityCache) {
	            return Private.specificityCache[selector];
	        }
	        var result = Private.calculateSingle(selector);
	        return Private.specificityCache[selector] = result;
	    }
	    Selector.calculateSpecificity = calculateSpecificity;
	    /**
	     * Test whether a selector is a valid CSS selector.
	     *
	     * @param selector - The CSS selector of interest.
	     *
	     * @returns `true` if the selector is valid, `false` otherwise.
	     *
	     * #### Notes
	     * The computed result is cached, so subsequent tests for the same
	     * selector are extremely fast.
	     */
	    function isValid(selector) {
	        if (selector in Private.validityCache) {
	            return Private.validityCache[selector];
	        }
	        var result = true;
	        try {
	            Private.testElem.querySelector(selector);
	        }
	        catch (err) {
	            result = false;
	        }
	        return Private.validityCache[selector] = result;
	    }
	    Selector.isValid = isValid;
	    /**
	     * Test whether an element matches a CSS selector.
	     *
	     * @param element - The element of interest.
	     *
	     * @param selector - The valid CSS selector of interest.
	     *
	     * @returns `true` if the element is a match, `false` otherwise.
	     *
	     * #### Notes
	     * This function uses the builtin browser capabilities when possible,
	     * falling back onto a document query otherwise.
	     */
	    function matches(element, selector) {
	        return Private.protoMatchFunc.call(element, selector);
	    }
	    Selector.matches = matches;
	})(Selector = exports.Selector || (exports.Selector = {}));
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A cache of computed selector specificity values.
	     */
	    Private.specificityCache = Object.create(null);
	    /**
	     * A cache of computed selector validity.
	     */
	    Private.validityCache = Object.create(null);
	    /**
	     * An empty element for testing selector validity.
	     */
	    Private.testElem = document.createElement('div');
	    /**
	     * A cross-browser CSS selector matching prototype function.
	     */
	    Private.protoMatchFunc = (function () {
	        var proto = Element.prototype;
	        return (proto.matches ||
	            proto.matchesSelector ||
	            proto.mozMatchesSelector ||
	            proto.msMatchesSelector ||
	            proto.oMatchesSelector ||
	            proto.webkitMatchesSelector ||
	            (function (selector) {
	                var elem = this;
	                var matches = elem.ownerDocument.querySelectorAll(selector);
	                return Array.prototype.indexOf.call(matches, elem) !== -1;
	            }));
	    })();
	    /**
	     * Calculate the specificity of a single selector.
	     *
	     * The behavior is undefined if the selector is invalid.
	     */
	    function calculateSingle(selector) {
	        // Ignore anything after the first comma.
	        selector = selector.split(',', 1)[0];
	        // Setup the aggregate counters.
	        var a = 0;
	        var b = 0;
	        var c = 0;
	        // Apply a regex to the front of the selector. If it succeeds, that
	        // portion of the selector is removed. Returns a success/fail flag.
	        function match(re) {
	            var match = selector.match(re);
	            if (match === null) {
	                return false;
	            }
	            selector = selector.slice(match[0].length);
	            return true;
	        }
	        // Replace the negation pseudo-class (which is ignored),
	        // but keep its inner content (which is not ignored).
	        selector = selector.replace(NEGATION_RE, ' $1 ');
	        // Continue matching until the selector is consumed.
	        while (selector.length > 0) {
	            // Match an ID selector.
	            if (match(ID_RE)) {
	                a++;
	                continue;
	            }
	            // Match a class selector.
	            if (match(CLASS_RE)) {
	                b++;
	                continue;
	            }
	            // Match an attribute selector.
	            if (match(ATTR_RE)) {
	                b++;
	                continue;
	            }
	            // Match a pseudo-element selector. This is done before matching
	            // a pseudo-class since this regex overlaps with that regex.
	            if (match(PSEUDO_ELEM_RE)) {
	                c++;
	                continue;
	            }
	            // Match a pseudo-class selector.
	            if (match(PSEDUO_CLASS_RE)) {
	                b++;
	                continue;
	            }
	            // Match a plain type selector.
	            if (match(TYPE_RE)) {
	                c++;
	                continue;
	            }
	            // Finally, match any ignored characters.
	            if (match(IGNORE_RE)) {
	                continue;
	            }
	            // At this point, the selector is assumed to be invalid.
	            return 0;
	        }
	        // Clamp each component to a reasonable base.
	        a = Math.min(a, 0xFF);
	        b = Math.min(b, 0xFF);
	        c = Math.min(c, 0xFF);
	        // Combine the components into a single result.
	        return (a << 16) | (b << 8) | c;
	    }
	    Private.calculateSingle = calculateSingle;
	    /**
	     * A regex which matches an ID selector at string start.
	     */
	    var ID_RE = /^#[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches a class selector at string start.
	     */
	    var CLASS_RE = /^\.[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches an attribute selector at string start.
	     */
	    var ATTR_RE = /^\[[^\]]+\]/;
	    /**
	     * A regex which matches a type selector at string start.
	     */
	    var TYPE_RE = /^[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches a pseudo-element selector at string start.
	     */
	    var PSEUDO_ELEM_RE = /^(::[^\s\+>~#\.\[:]+|:first-line|:first-letter|:before|:after)/;
	    /**
	     * A regex which matches a pseudo-class selector at string start.
	     */
	    var PSEDUO_CLASS_RE = /^:[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches ignored characters at string start.
	     */
	    var IGNORE_RE = /^[\s\+>~\*]+/;
	    /**
	     * A regex which matches the negation pseudo-class globally.
	     */
	    var NEGATION_RE = /:not\(([^\)]+)\)/g;
	})(Private || (Private = {}));


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

	/* WEBPACK VAR INJECTION */(function(setImmediate, clearImmediate) {"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var collections_1 = __webpack_require__(197);
	/**
	 * A message which can be delivered to a message handler.
	 *
	 * #### Notes
	 * This class may be subclassed to create complex message types.
	 */
	var Message = (function () {
	    /**
	     * Construct a new message.
	     *
	     * @param type - The type of the message.
	     */
	    function Message(type) {
	        this.type = type;
	    }
	    Object.defineProperty(Message.prototype, "isConflatable", {
	        /**
	         * Test whether the message is conflatable.
	         *
	         * #### Notes
	         * Message conflation is an advanced topic. Most message types will
	         * not make use of this feature.
	         *
	         * If a conflatable message is posted to a handler while another
	         * conflatable message of the same `type` has already been posted
	         * to the handler, the `conflate()` method of the existing message
	         * will be invoked. If that method returns `true`, the new message
	         * will not be enqueued. This allows messages to be compressed, so
	         * that only a single instance of the message type is processed per
	         * cycle, no matter how many times messages of that type are posted.
	         *
	         * Custom message types may reimplement this property.
	         *
	         * The default implementation is always `false`.
	         */
	        get: function () {
	            return false;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Conflate this message with another message of the same `type`.
	     *
	     * @param other - A conflatable message of the same `type`.
	     *
	     * @returns `true` if the message was successfully conflated, or
	     *   `false` otherwise.
	     *
	     * #### Notes
	     * Message conflation is an advanced topic. Most message types will
	     * not make use of this feature.
	     *
	     * This method is called automatically by the message loop when the
	     * given message is posted to the handler paired with this message.
	     * This message will already be enqueued and conflatable, and the
	     * given message will have the same `type` and also be conflatable.
	     *
	     * This method should merge the state of the other message into this
	     * message as needed so that when this message is finally delivered
	     * to the handler, it receives the most up-to-date information.
	     *
	     * If this method returns `true`, it signals that the other message
	     * was successfully conflated and that message will not be enqueued.
	     *
	     * If this method returns `false`, the other message will be enqueued
	     * for normal delivery.
	     *
	     * Custom message types may reimplement this method.
	     *
	     * The default implementation always returns `false`.
	     */
	    Message.prototype.conflate = function (other) {
	        return false;
	    };
	    return Message;
	}());
	exports.Message = Message;
	/**
	 * A convenience message class which conflates automatically.
	 *
	 * #### Notes
	 * Message conflation is an advanced topic. Most user code will not
	 * make use of this class.
	 *
	 * This message class is useful for creating message instances which
	 * should be conflated, but which have no state other than `type`.
	 *
	 * If conflation of stateful messages is required, a custom `Message`
	 * subclass should be created.
	 */
	var ConflatableMessage = (function (_super) {
	    __extends(ConflatableMessage, _super);
	    function ConflatableMessage() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    Object.defineProperty(ConflatableMessage.prototype, "isConflatable", {
	        /**
	         * Test whether the message is conflatable.
	         *
	         * #### Notes
	         * This property is always `true`.
	         */
	        get: function () {
	            return true;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Conflate this message with another message of the same `type`.
	     *
	     * #### Notes
	     * This method always returns `true`.
	     */
	    ConflatableMessage.prototype.conflate = function (other) {
	        return true;
	    };
	    return ConflatableMessage;
	}(Message));
	exports.ConflatableMessage = ConflatableMessage;
	/**
	 * The namespace for the global singleton message loop.
	 */
	var MessageLoop;
	(function (MessageLoop) {
	    /**
	     * Send a message to a message handler to process immediately.
	     *
	     * @param handler - The handler which should process the message.
	     *
	     * @param msg - The message to deliver to the handler.
	     *
	     * #### Notes
	     * The message will first be sent through any installed message hooks
	     * for the handler. If the message passes all hooks, it will then be
	     * delivered to the `processMessage` method of the handler.
	     *
	     * The message will not be conflated with pending posted messages.
	     *
	     * Exceptions in hooks and handlers will be caught and logged.
	     */
	    function sendMessage(handler, msg) {
	        // Lookup the message hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Handle the common case of no installed hooks.
	        if (!hooks || hooks.length === 0) {
	            invokeHandler(handler, msg);
	            return;
	        }
	        // Invoke the message hooks starting with the newest first.
	        var passed = algorithm_1.every(algorithm_1.retro(hooks), function (hook) {
	            return hook ? invokeHook(hook, handler, msg) : true;
	        });
	        // Invoke the handler if the message passes all hooks.
	        if (passed) {
	            invokeHandler(handler, msg);
	        }
	    }
	    MessageLoop.sendMessage = sendMessage;
	    /**
	     * Post a message to a message handler to process in the future.
	     *
	     * @param handler - The handler which should process the message.
	     *
	     * @param msg - The message to post to the handler.
	     *
	     * #### Notes
	     * The message will be conflated with the pending posted messages for
	     * the handler, if possible. If the message is not conflated, it will
	     * be queued for normal delivery on the next cycle of the event loop.
	     *
	     * Exceptions in hooks and handlers will be caught and logged.
	     */
	    function postMessage(handler, msg) {
	        // Handle the common case of a non-conflatable message.
	        if (!msg.isConflatable) {
	            enqueueMessage(handler, msg);
	            return;
	        }
	        // Conflate the message with an existing message if possible.
	        var conflated = algorithm_1.some(messageQueue, function (posted) {
	            if (posted.handler !== handler) {
	                return false;
	            }
	            if (!posted.msg) {
	                return false;
	            }
	            if (posted.msg.type !== msg.type) {
	                return false;
	            }
	            if (!posted.msg.isConflatable) {
	                return false;
	            }
	            return posted.msg.conflate(msg);
	        });
	        // Enqueue the message if it was not conflated.
	        if (!conflated) {
	            enqueueMessage(handler, msg);
	        }
	    }
	    MessageLoop.postMessage = postMessage;
	    /**
	     * Install a message hook for a message handler.
	     *
	     * @param handler - The message handler of interest.
	     *
	     * @param hook - The message hook to install.
	     *
	     * #### Notes
	     * A message hook is invoked before a message is delivered to the
	     * handler. If the hook returns `false`, no other hooks will be
	     * invoked and the message will not be delivered to the handler.
	     *
	     * The most recently installed message hook is executed first.
	     *
	     * If the hook is already installed, this is a no-op.
	     */
	    function installMessageHook(handler, hook) {
	        // Lookup the hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Bail early if the hook is already installed.
	        if (hooks && hooks.indexOf(hook) !== -1) {
	            return;
	        }
	        // Add the hook to the end, so it will be the first to execute.
	        if (!hooks) {
	            messageHooks.set(handler, [hook]);
	        }
	        else {
	            hooks.push(hook);
	        }
	    }
	    MessageLoop.installMessageHook = installMessageHook;
	    /**
	     * Remove an installed message hook for a message handler.
	     *
	     * @param handler - The message handler of interest.
	     *
	     * @param hook - The message hook to remove.
	     *
	     * #### Notes
	     * It is safe to call this function while the hook is executing.
	     *
	     * If the hook is not installed, this is a no-op.
	     */
	    function removeMessageHook(handler, hook) {
	        // Lookup the hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Bail early if the hooks do not exist.
	        if (!hooks) {
	            return;
	        }
	        // Lookup the index of the hook and bail if not found.
	        var i = hooks.indexOf(hook);
	        if (i === -1) {
	            return;
	        }
	        // Clear the hook and schedule a cleanup of the array.
	        hooks[i] = null;
	        scheduleCleanup(hooks);
	    }
	    MessageLoop.removeMessageHook = removeMessageHook;
	    /**
	     * Clear all message data associated with a message handler.
	     *
	     * @param handler - The message handler of interest.
	     *
	     * #### Notes
	     * This will clear all posted messages and hooks for the handler.
	     */
	    function clearData(handler) {
	        // Lookup the hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Clear all messsage hooks for the handler.
	        if (hooks && hooks.length > 0) {
	            algorithm_1.ArrayExt.fill(hooks, null);
	            scheduleCleanup(hooks);
	        }
	        // Clear all posted messages for the handler.
	        algorithm_1.each(messageQueue, function (posted) {
	            if (posted.handler === handler) {
	                posted.handler = null;
	                posted.msg = null;
	            }
	        });
	    }
	    MessageLoop.clearData = clearData;
	    /**
	     * Process the pending posted messages in the queue immediately.
	     *
	     * #### Notes
	     * This function is useful when posted messages must be processed
	     * immediately, instead of on the next animation frame.
	     *
	     * This function should normally not be needed, but it may be
	     * required to work around certain browser idiosyncrasies.
	     *
	     * Recursing into this function is a no-op.
	     */
	    function flush() {
	        // Bail if recursion is detected or if there is no pending task.
	        if (flushGuard || loopTaskID === 0) {
	            return;
	        }
	        // Unschedule the pending loop task.
	        unschedule(loopTaskID);
	        // Run the message loop within the recursion guard.
	        flushGuard = true;
	        runMessageLoop();
	        flushGuard = false;
	    }
	    MessageLoop.flush = flush;
	    /**
	     * Get the message loop exception handler.
	     *
	     * @returns The current exception handler.
	     *
	     * #### Notes
	     * The default exception handler is `console.error`.
	     */
	    function getExceptionHandler() {
	        return exceptionHandler;
	    }
	    MessageLoop.getExceptionHandler = getExceptionHandler;
	    /**
	     * Set the message loop exception handler.
	     *
	     * @param handler - The function to use as the exception handler.
	     *
	     * @returns The old exception handler.
	     *
	     * #### Notes
	     * The exception handler is invoked when a message handler or a
	     * message hook throws an exception.
	     */
	    function setExceptionHandler(handler) {
	        var old = exceptionHandler;
	        exceptionHandler = handler;
	        return old;
	    }
	    MessageLoop.setExceptionHandler = setExceptionHandler;
	    /**
	     * The queue of posted message pairs.
	     */
	    var messageQueue = new collections_1.LinkedList();
	    /**
	     * A mapping of handler to array of installed message hooks.
	     */
	    var messageHooks = new WeakMap();
	    /**
	     * A set of message hook arrays which are pending cleanup.
	     */
	    var dirtySet = new Set();
	    /**
	     * The message loop exception handler.
	     */
	    var exceptionHandler = function (err) {
	        console.error(err);
	    };
	    /**
	     * The id of the pending loop task animation frame.
	     */
	    var loopTaskID = 0;
	    /**
	     * A guard flag to prevent flush recursion.
	     */
	    var flushGuard = false;
	    /**
	     * A function to schedule an event loop callback.
	     */
	    var schedule = (function () {
	        var ok = typeof requestAnimationFrame === 'function';
	        return ok ? requestAnimationFrame : setImmediate;
	    })();
	    /**
	     * A function to unschedule an event loop callback.
	     */
	    var unschedule = (function () {
	        var ok = typeof cancelAnimationFrame === 'function';
	        return ok ? cancelAnimationFrame : clearImmediate;
	    })();
	    /**
	     * Invoke a message hook with the specified handler and message.
	     *
	     * Returns the result of the hook, or `true` if the hook throws.
	     *
	     * Exceptions in the hook will be caught and logged.
	     */
	    function invokeHook(hook, handler, msg) {
	        var result = true;
	        try {
	            if (typeof hook === 'function') {
	                result = hook(handler, msg);
	            }
	            else {
	                result = hook.messageHook(handler, msg);
	            }
	        }
	        catch (err) {
	            exceptionHandler(err);
	        }
	        return result;
	    }
	    /**
	     * Invoke a message handler with the specified message.
	     *
	     * Exceptions in the handler will be caught and logged.
	     */
	    function invokeHandler(handler, msg) {
	        try {
	            handler.processMessage(msg);
	        }
	        catch (err) {
	            exceptionHandler(err);
	        }
	    }
	    /**
	     * Add a message to the end of the message queue.
	     *
	     * This will automatically schedule a run of the message loop.
	     */
	    function enqueueMessage(handler, msg) {
	        // Add the posted message to the queue.
	        messageQueue.addLast({ handler: handler, msg: msg });
	        // Bail if a loop task is already pending.
	        if (loopTaskID !== 0) {
	            return;
	        }
	        // Schedule a run of the message loop.
	        loopTaskID = schedule(runMessageLoop);
	    }
	    /**
	     * Run an iteration of the message loop.
	     *
	     * This will process all pending messages in the queue. If a message
	     * is added to the queue while the message loop is running, it will
	     * be processed on the next cycle of the loop.
	     */
	    function runMessageLoop() {
	        // Clear the task ID so the next loop can be scheduled.
	        loopTaskID = 0;
	        // If the message queue is empty, there is nothing else to do.
	        if (messageQueue.isEmpty) {
	            return;
	        }
	        // Add a sentinel value to the end of the queue. The queue will
	        // only be processed up to the sentinel. Messages posted during
	        // this cycle will execute on the next cycle.
	        var sentinel = { handler: null, msg: null };
	        messageQueue.addLast(sentinel);
	        // Enter the message loop.
	        while (true) {
	            // Remove the first posted message in the queue.
	            var posted = messageQueue.removeFirst();
	            // If the value is the sentinel, exit the loop.
	            if (posted === sentinel) {
	                return;
	            }
	            // Dispatch the message if it has not been cleared.
	            if (posted.handler && posted.msg) {
	                sendMessage(posted.handler, posted.msg);
	            }
	        }
	    }
	    /**
	     * Schedule a cleanup of a message hooks array.
	     *
	     * This will add the array to the dirty set and schedule a deferred
	     * cleanup of the array contents. On cleanup, any `null` hook will
	     * be removed from the array.
	     */
	    function scheduleCleanup(hooks) {
	        if (dirtySet.size === 0) {
	            schedule(cleanupDirtySet);
	        }
	        dirtySet.add(hooks);
	    }
	    /**
	     * Cleanup the message hook arrays in the dirty set.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupDirtySet() {
	        dirtySet.forEach(cleanupHooks);
	        dirtySet.clear();
	    }
	    /**
	     * Cleanup the dirty hooks in a message hooks array.
	     *
	     * This will remove any `null` hook from the array.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupHooks(hooks) {
	        algorithm_1.ArrayExt.removeAllWhere(hooks, isNull);
	    }
	    /**
	     * Test whether a value is `null`.
	     */
	    function isNull(value) {
	        return value === null;
	    }
	})(MessageLoop = exports.MessageLoop || (exports.MessageLoop = {}));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(51).setImmediate, __webpack_require__(51).clearImmediate))

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

	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__webpack_require__(198));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	/**
	 * A generic doubly-linked list.
	 */
	var LinkedList = (function () {
	    /**
	     * Construct a new linked list.
	     */
	    function LinkedList() {
	        this._first = null;
	        this._last = null;
	        this._length = 0;
	    }
	    Object.defineProperty(LinkedList.prototype, "isEmpty", {
	        /**
	         * Whether the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._length === 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "length", {
	        /**
	         * The length of the list.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._length;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "first", {
	        /**
	         * The first value in the list.
	         *
	         * This is `undefined` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._first ? this._first.value : undefined;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "last", {
	        /**
	         * The last value in the list.
	         *
	         * This is `undefined` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._last ? this._last.value : undefined;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "firstNode", {
	        /**
	         * The first node in the list.
	         *
	         * This is `null` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._first;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "lastNode", {
	        /**
	         * The last node in the list.
	         *
	         * This is `null` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._last;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the values in the list.
	     *
	     * @returns A new iterator starting with the first value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.iter = function () {
	        return new LinkedList.ForwardValueIterator(this._first);
	    };
	    /**
	     * Create a reverse iterator over the values in the list.
	     *
	     * @returns A new iterator starting with the last value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.retro = function () {
	        return new LinkedList.RetroValueIterator(this._last);
	    };
	    /**
	     * Create an iterator over the nodes in the list.
	     *
	     * @returns A new iterator starting with the first node.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.nodes = function () {
	        return new LinkedList.ForwardNodeIterator(this._first);
	    };
	    /**
	     * Create a reverse iterator over the nodes in the list.
	     *
	     * @returns A new iterator starting with the last node.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.retroNodes = function () {
	        return new LinkedList.RetroNodeIterator(this._last);
	    };
	    /**
	     * Add a value to the beginning of the list.
	     *
	     * @param value - The value to add to the beginning of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.addFirst = function (value) {
	        var node = new Private.LinkedListNode(this, value);
	        if (!this._first) {
	            this._first = node;
	            this._last = node;
	        }
	        else {
	            node.next = this._first;
	            this._first.prev = node;
	            this._first = node;
	        }
	        this._length++;
	        return node;
	    };
	    /**
	     * Add a value to the end of the list.
	     *
	     * @param value - The value to add to the end of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.addLast = function (value) {
	        var node = new Private.LinkedListNode(this, value);
	        if (!this._last) {
	            this._first = node;
	            this._last = node;
	        }
	        else {
	            node.prev = this._last;
	            this._last.next = node;
	            this._last = node;
	        }
	        this._length++;
	        return node;
	    };
	    /**
	     * Insert a value before a specific node in the list.
	     *
	     * @param value - The value to insert before the reference node.
	     *
	     * @param ref - The reference node of interest. If this is `null`,
	     *   the value will be added to the beginning of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Notes
	     * The reference node must be owned by the list.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.insertBefore = function (value, ref) {
	        if (!ref || ref === this._first) {
	            return this.addFirst(value);
	        }
	        if (!(ref instanceof Private.LinkedListNode) || ref.list !== this) {
	            throw new Error('Reference node is not owned by the list.');
	        }
	        var node = new Private.LinkedListNode(this, value);
	        var _ref = ref;
	        var prev = _ref.prev;
	        node.next = _ref;
	        node.prev = prev;
	        _ref.prev = node;
	        prev.next = node;
	        this._length++;
	        return node;
	    };
	    /**
	     * Insert a value after a specific node in the list.
	     *
	     * @param value - The value to insert after the reference node.
	     *
	     * @param ref - The reference node of interest. If this is `null`,
	     *   the value will be added to the end of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Notes
	     * The reference node must be owned by the list.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.insertAfter = function (value, ref) {
	        if (!ref || ref === this._last) {
	            return this.addLast(value);
	        }
	        if (!(ref instanceof Private.LinkedListNode) || ref.list !== this) {
	            throw new Error('Reference node is not owned by the list.');
	        }
	        var node = new Private.LinkedListNode(this, value);
	        var _ref = ref;
	        var next = _ref.next;
	        node.next = next;
	        node.prev = _ref;
	        _ref.next = node;
	        next.prev = node;
	        this._length++;
	        return node;
	    };
	    /**
	     * Remove and return the value at the beginning of the list.
	     *
	     * @returns The removed value, or `undefined` if the list is empty.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.removeFirst = function () {
	        var node = this._first;
	        if (!node) {
	            return undefined;
	        }
	        if (node === this._last) {
	            this._first = null;
	            this._last = null;
	        }
	        else {
	            this._first = node.next;
	            this._first.prev = null;
	        }
	        node.list = null;
	        node.next = null;
	        node.prev = null;
	        this._length--;
	        return node.value;
	    };
	    /**
	     * Remove and return the value at the end of the list.
	     *
	     * @returns The removed value, or `undefined` if the list is empty.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.removeLast = function () {
	        var node = this._last;
	        if (!node) {
	            return undefined;
	        }
	        if (node === this._first) {
	            this._first = null;
	            this._last = null;
	        }
	        else {
	            this._last = node.prev;
	            this._last.next = null;
	        }
	        node.list = null;
	        node.next = null;
	        node.prev = null;
	        this._length--;
	        return node.value;
	    };
	    /**
	     * Remove a specific node from the list.
	     *
	     * @param node - The node to remove from the list.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Notes
	     * The node must be owned by the list.
	     */
	    LinkedList.prototype.removeNode = function (node) {
	        if (!(node instanceof Private.LinkedListNode) || node.list !== this) {
	            throw new Error('Node is not owned by the list.');
	        }
	        var _node = node;
	        if (_node === this._first && _node === this._last) {
	            this._first = null;
	            this._last = null;
	        }
	        else if (_node === this._first) {
	            this._first = _node.next;
	            this._first.prev = null;
	        }
	        else if (_node === this._last) {
	            this._last = _node.prev;
	            this._last.next = null;
	        }
	        else {
	            _node.next.prev = _node.prev;
	            _node.prev.next = _node.next;
	        }
	        _node.list = null;
	        _node.next = null;
	        _node.prev = null;
	        this._length--;
	    };
	    /**
	     * Remove all values from the list.
	     *
	     * #### Complexity
	     * Linear.
	     */
	    LinkedList.prototype.clear = function () {
	        var node = this._first;
	        while (node) {
	            var next = node.next;
	            node.list = null;
	            node.prev = null;
	            node.next = null;
	            node = next;
	        }
	        this._first = null;
	        this._last = null;
	        this._length = 0;
	    };
	    return LinkedList;
	}());
	exports.LinkedList = LinkedList;
	/**
	 * The namespace for the `LinkedList` class statics.
	 */
	(function (LinkedList) {
	    /**
	     * Create a linked list from an iterable of values.
	     *
	     * @param values - The iterable or array-like object of interest.
	     *
	     * @returns A new linked list initialized with the given values.
	     */
	    function from(values) {
	        var list = new LinkedList();
	        algorithm_1.each(values, function (value) { list.addLast(value); });
	        return list;
	    }
	    LinkedList.from = from;
	    /**
	     * A forward iterator for values in a linked list.
	     */
	    var ForwardValueIterator = (function () {
	        /**
	         * Construct a forward value iterator.
	         *
	         * @param node - The first node in the list.
	         */
	        function ForwardValueIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        ForwardValueIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        ForwardValueIterator.prototype.clone = function () {
	            return new ForwardValueIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        ForwardValueIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.next;
	            return node.value;
	        };
	        return ForwardValueIterator;
	    }());
	    LinkedList.ForwardValueIterator = ForwardValueIterator;
	    /**
	     * A reverse iterator for values in a linked list.
	     */
	    var RetroValueIterator = (function () {
	        /**
	         * Construct a retro value iterator.
	         *
	         * @param node - The last node in the list.
	         */
	        function RetroValueIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        RetroValueIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        RetroValueIterator.prototype.clone = function () {
	            return new RetroValueIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        RetroValueIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.prev;
	            return node.value;
	        };
	        return RetroValueIterator;
	    }());
	    LinkedList.RetroValueIterator = RetroValueIterator;
	    /**
	     * A forward iterator for nodes in a linked list.
	     */
	    var ForwardNodeIterator = (function () {
	        /**
	         * Construct a forward node iterator.
	         *
	         * @param node - The first node in the list.
	         */
	        function ForwardNodeIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        ForwardNodeIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        ForwardNodeIterator.prototype.clone = function () {
	            return new ForwardNodeIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        ForwardNodeIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.next;
	            return node;
	        };
	        return ForwardNodeIterator;
	    }());
	    LinkedList.ForwardNodeIterator = ForwardNodeIterator;
	    /**
	     * A reverse iterator for nodes in a linked list.
	     */
	    var RetroNodeIterator = (function () {
	        /**
	         * Construct a retro node iterator.
	         *
	         * @param node - The last node in the list.
	         */
	        function RetroNodeIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        RetroNodeIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        RetroNodeIterator.prototype.clone = function () {
	            return new RetroNodeIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        RetroNodeIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.prev;
	            return node;
	        };
	        return RetroNodeIterator;
	    }());
	    LinkedList.RetroNodeIterator = RetroNodeIterator;
	})(LinkedList = exports.LinkedList || (exports.LinkedList = {}));
	exports.LinkedList = LinkedList;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The internal linked list node implementation.
	     */
	    var LinkedListNode = (function () {
	        /**
	         * Construct a new linked list node.
	         *
	         * @param list - The list which owns the node.
	         *
	         * @param value - The value for the link.
	         */
	        function LinkedListNode(list, value) {
	            /**
	             * The linked list which created and owns the node.
	             */
	            this.list = null;
	            /**
	             * The next node in the list.
	             */
	            this.next = null;
	            /**
	             * The previous node in the list.
	             */
	            this.prev = null;
	            this.list = list;
	            this.value = value;
	        }
	        return LinkedListNode;
	    }());
	    Private.LinkedListNode = LinkedListNode;
	})(Private || (Private = {}));


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A class which attaches a value to an external object.
	 *
	 * #### Notes
	 * Attached properties are used to extend the state of an object with
	 * semantic data from an unrelated class. They also encapsulate value
	 * creation, coercion, and notification.
	 *
	 * Because attached property values are stored in a hash table, which
	 * in turn is stored in a WeakMap keyed on the owner object, there is
	 * non-trivial storage overhead involved in their use. The pattern is
	 * therefore best used for the storage of rare data.
	 */
	var AttachedProperty = (function () {
	    /**
	     * Construct a new attached property.
	     *
	     * @param options - The options for initializing the property.
	     */
	    function AttachedProperty(options) {
	        this._pid = Private.nextPID();
	        this.name = options.name;
	        this._create = options.create;
	        this._coerce = options.coerce || null;
	        this._compare = options.compare || null;
	        this._changed = options.changed || null;
	    }
	    /**
	     * Get the current value of the property for a given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * @returns The current value of the property.
	     *
	     * #### Notes
	     * If the value has not yet been set, the default value will be
	     * computed and assigned as the current value of the property.
	     */
	    AttachedProperty.prototype.get = function (owner) {
	        var value;
	        var map = Private.ensureMap(owner);
	        if (this._pid in map) {
	            value = map[this._pid];
	        }
	        else {
	            value = map[this._pid] = this._createValue(owner);
	        }
	        return value;
	    };
	    /**
	     * Set the current value of the property for a given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * @param value - The value for the property.
	     *
	     * #### Notes
	     * If the value has not yet been set, the default value will be
	     * computed and used as the previous value for the comparison.
	     */
	    AttachedProperty.prototype.set = function (owner, value) {
	        var oldValue;
	        var map = Private.ensureMap(owner);
	        if (this._pid in map) {
	            oldValue = map[this._pid];
	        }
	        else {
	            oldValue = map[this._pid] = this._createValue(owner);
	        }
	        var newValue = this._coerceValue(owner, value);
	        this._maybeNotify(owner, oldValue, map[this._pid] = newValue);
	    };
	    /**
	     * Explicitly coerce the current property value for a given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * #### Notes
	     * If the value has not yet been set, the default value will be
	     * computed and used as the previous value for the comparison.
	     */
	    AttachedProperty.prototype.coerce = function (owner) {
	        var oldValue;
	        var map = Private.ensureMap(owner);
	        if (this._pid in map) {
	            oldValue = map[this._pid];
	        }
	        else {
	            oldValue = map[this._pid] = this._createValue(owner);
	        }
	        var newValue = this._coerceValue(owner, oldValue);
	        this._maybeNotify(owner, oldValue, map[this._pid] = newValue);
	    };
	    /**
	     * Get or create the default value for the given owner.
	     */
	    AttachedProperty.prototype._createValue = function (owner) {
	        var create = this._create;
	        return create(owner);
	    };
	    /**
	     * Coerce the value for the given owner.
	     */
	    AttachedProperty.prototype._coerceValue = function (owner, value) {
	        var coerce = this._coerce;
	        return coerce ? coerce(owner, value) : value;
	    };
	    /**
	     * Compare the old value and new value for equality.
	     */
	    AttachedProperty.prototype._compareValue = function (oldValue, newValue) {
	        var compare = this._compare;
	        return compare ? compare(oldValue, newValue) : oldValue === newValue;
	    };
	    /**
	     * Run the change notification if the given values are different.
	     */
	    AttachedProperty.prototype._maybeNotify = function (owner, oldValue, newValue) {
	        var changed = this._changed;
	        if (changed && !this._compareValue(oldValue, newValue)) {
	            changed(owner, oldValue, newValue);
	        }
	    };
	    return AttachedProperty;
	}());
	exports.AttachedProperty = AttachedProperty;
	/**
	 * The namespace for the `AttachedProperty` class statics.
	 */
	(function (AttachedProperty) {
	    /**
	     * Clear the stored property data for the given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * #### Notes
	     * This will clear all property values for the owner, but it will
	     * **not** run the change notification for any of the properties.
	     */
	    function clearData(owner) {
	        Private.ownerData.delete(owner);
	    }
	    AttachedProperty.clearData = clearData;
	})(AttachedProperty = exports.AttachedProperty || (exports.AttachedProperty = {}));
	exports.AttachedProperty = AttachedProperty;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A weak mapping of property owner to property map.
	     */
	    Private.ownerData = new WeakMap();
	    /**
	     * A function which computes successive unique property ids.
	     */
	    Private.nextPID = (function () {
	        var id = 0;
	        return function () {
	            var rand = Math.random();
	            var stem = ("" + rand).slice(2);
	            return "pid-" + stem + "-" + id++;
	        };
	    })();
	    /**
	     * Lookup the data map for the property owner.
	     *
	     * This will create the map if one does not already exist.
	     */
	    function ensureMap(owner) {
	        var map = Private.ownerData.get(owner);
	        if (map) {
	            return map;
	        }
	        map = Object.create(null);
	        Private.ownerData.set(owner, map);
	        return map;
	    }
	    Private.ensureMap = ensureMap;
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var messaging_1 = __webpack_require__(196);
	var properties_1 = __webpack_require__(199);
	var signaling_1 = __webpack_require__(201);
	var widget_1 = __webpack_require__(202);
	/**
	 * An abstract base class for creating Phosphor layouts.
	 *
	 * #### Notes
	 * A layout is used to add widgets to a parent and to arrange those
	 * widgets within the parent's DOM node.
	 *
	 * This class implements the base functionality which is required of
	 * nearly all layouts. It must be subclassed in order to be useful.
	 *
	 * Notably, this class does not define a uniform interface for adding
	 * widgets to the layout. A subclass should define that API in a way
	 * which is meaningful for its intended use.
	 */
	var Layout = (function () {
	    /**
	     * Construct a new layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function Layout(options) {
	        if (options === void 0) { options = {}; }
	        this._disposed = false;
	        this._parent = null;
	        this._fitPolicy = options.fitPolicy || 'set-min-size';
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This should be reimplemented to clear and dispose of the widgets.
	     *
	     * All reimplementations should call the superclass method.
	     *
	     * This method is called automatically when the parent is disposed.
	     */
	    Layout.prototype.dispose = function () {
	        this._parent = null;
	        this._disposed = true;
	        signaling_1.Signal.clearData(this);
	        properties_1.AttachedProperty.clearData(this);
	    };
	    Object.defineProperty(Layout.prototype, "isDisposed", {
	        /**
	         * Test whether the layout is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Layout.prototype, "parent", {
	        /**
	         * Get the parent widget of the layout.
	         */
	        get: function () {
	            return this._parent;
	        },
	        /**
	         * Set the parent widget of the layout.
	         *
	         * #### Notes
	         * This is set automatically when installing the layout on the parent
	         * widget. The parent widget should not be set directly by user code.
	         */
	        set: function (value) {
	            if (this._parent === value) {
	                return;
	            }
	            if (this._parent) {
	                throw new Error('Cannot change parent widget.');
	            }
	            if (value.layout !== this) {
	                throw new Error('Invalid parent widget.');
	            }
	            this._parent = value;
	            this.init();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Layout.prototype, "fitPolicy", {
	        /**
	         * Get the fit policy for the layout.
	         *
	         * #### Notes
	         * The fit policy controls the computed size constraints which are
	         * applied to the parent widget by the layout.
	         *
	         * Some layout implementations may ignore the fit policy.
	         */
	        get: function () {
	            return this._fitPolicy;
	        },
	        /**
	         * Set the fit policy for the layout.
	         *
	         * #### Notes
	         * The fit policy controls the computed size constraints which are
	         * applied to the parent widget by the layout.
	         *
	         * Some layout implementations may ignore the fit policy.
	         *
	         * Changing the fit policy will clear the current size constraint
	         * for the parent widget and then re-fit the parent.
	         */
	        set: function (value) {
	            // Bail if the policy does not change
	            if (this._fitPolicy === value) {
	                return;
	            }
	            // Update the internal policy.
	            this._fitPolicy = value;
	            // Clear the size constraints and schedule a fit of the parent.
	            if (this._parent) {
	                var style = this._parent.node.style;
	                style.minWidth = '';
	                style.minHeight = '';
	                style.maxWidth = '';
	                style.maxHeight = '';
	                this._parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Process a message sent to the parent widget.
	     *
	     * @param msg - The message sent to the parent widget.
	     *
	     * #### Notes
	     * This method is called by the parent widget to process a message.
	     *
	     * Subclasses may reimplement this method as needed.
	     */
	    Layout.prototype.processParentMessage = function (msg) {
	        switch (msg.type) {
	            case 'resize':
	                this.onResize(msg);
	                break;
	            case 'update-request':
	                this.onUpdateRequest(msg);
	                break;
	            case 'fit-request':
	                this.onFitRequest(msg);
	                break;
	            case 'before-show':
	                this.onBeforeShow(msg);
	                break;
	            case 'after-show':
	                this.onAfterShow(msg);
	                break;
	            case 'before-hide':
	                this.onBeforeHide(msg);
	                break;
	            case 'after-hide':
	                this.onAfterHide(msg);
	                break;
	            case 'before-attach':
	                this.onBeforeAttach(msg);
	                break;
	            case 'after-attach':
	                this.onAfterAttach(msg);
	                break;
	            case 'before-detach':
	                this.onBeforeDetach(msg);
	                break;
	            case 'after-detach':
	                this.onAfterDetach(msg);
	                break;
	            case 'child-removed':
	                this.onChildRemoved(msg);
	                break;
	            case 'child-shown':
	                this.onChildShown(msg);
	                break;
	            case 'child-hidden':
	                this.onChildHidden(msg);
	                break;
	        }
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     *
	     * #### Notes
	     * This method is invoked immediately after the layout is installed
	     * on the parent widget.
	     *
	     * The default implementation reparents all of the widgets to the
	     * layout parent widget.
	     *
	     * Subclasses should reimplement this method and attach the child
	     * widget nodes to the parent widget's node.
	     */
	    Layout.prototype.init = function () {
	        var _this = this;
	        algorithm_1.each(this, function (widget) {
	            widget.parent = _this.parent;
	        });
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     *
	     * #### Notes
	     * The layout should ensure that its widgets are resized according
	     * to the specified layout space, and that they are sent a `'resize'`
	     * message if appropriate.
	     *
	     * The default implementation of this method sends an `UnknownSize`
	     * resize message to all widgets.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onResize = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.ResizeMessage.UnknownSize);
	        });
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     *
	     * #### Notes
	     * The layout should ensure that its widgets are resized according
	     * to the available layout space, and that they are sent a `'resize'`
	     * message if appropriate.
	     *
	     * The default implementation of this method sends an `UnknownSize`
	     * resize message to all widgets.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onUpdateRequest = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.ResizeMessage.UnknownSize);
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeAttach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterAttach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeDetach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterDetach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeShow = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterShow = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeHide = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterHide = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     *
	     * #### Notes
	     * This will remove the child widget from the layout.
	     *
	     * Subclasses should **not** typically reimplement this method.
	     */
	    Layout.prototype.onChildRemoved = function (msg) {
	        this.removeWidget(msg.child);
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onFitRequest = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onChildShown = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onChildHidden = function (msg) { };
	    return Layout;
	}());
	exports.Layout = Layout;
	/**
	 * The namespace for the `Layout` class statics.
	 */
	(function (Layout) {
	    /**
	     * Get the horizontal alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The horizontal alignment for the widget.
	     *
	     * #### Notes
	     * If the layout width allocated to a widget is larger than its max
	     * width, the horizontal alignment controls how the widget is placed
	     * within the extra horizontal space.
	     *
	     * If the allocated width is less than the widget's max width, the
	     * horizontal alignment has no effect.
	     *
	     * Some layout implementations may ignore horizontal alignment.
	     */
	    function getHorizontalAlignment(widget) {
	        return Private.horizontalAlignmentProperty.get(widget);
	    }
	    Layout.getHorizontalAlignment = getHorizontalAlignment;
	    /**
	     * Set the horizontal alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the horizontal alignment.
	     *
	     * #### Notes
	     * If the layout width allocated to a widget is larger than its max
	     * width, the horizontal alignment controls how the widget is placed
	     * within the extra horizontal space.
	     *
	     * If the allocated width is less than the widget's max width, the
	     * horizontal alignment has no effect.
	     *
	     * Some layout implementations may ignore horizontal alignment.
	     *
	     * Changing the horizontal alignment will post an `update-request`
	     * message to widget's parent, provided the parent has a layout
	     * installed.
	     */
	    function setHorizontalAlignment(widget, value) {
	        Private.horizontalAlignmentProperty.set(widget, value);
	    }
	    Layout.setHorizontalAlignment = setHorizontalAlignment;
	    /**
	     * Get the vertical alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The vertical alignment for the widget.
	     *
	     * #### Notes
	     * If the layout height allocated to a widget is larger than its max
	     * height, the vertical alignment controls how the widget is placed
	     * within the extra vertical space.
	     *
	     * If the allocated height is less than the widget's max height, the
	     * vertical alignment has no effect.
	     *
	     * Some layout implementations may ignore vertical alignment.
	     */
	    function getVerticalAlignment(widget) {
	        return Private.verticalAlignmentProperty.get(widget);
	    }
	    Layout.getVerticalAlignment = getVerticalAlignment;
	    /**
	     * Set the vertical alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the vertical alignment.
	     *
	     * #### Notes
	     * If the layout height allocated to a widget is larger than its max
	     * height, the vertical alignment controls how the widget is placed
	     * within the extra vertical space.
	     *
	     * If the allocated height is less than the widget's max height, the
	     * vertical alignment has no effect.
	     *
	     * Some layout implementations may ignore vertical alignment.
	     *
	     * Changing the horizontal alignment will post an `update-request`
	     * message to widget's parent, provided the parent has a layout
	     * installed.
	     */
	    function setVerticalAlignment(widget, value) {
	        Private.verticalAlignmentProperty.set(widget, value);
	    }
	    Layout.setVerticalAlignment = setVerticalAlignment;
	})(Layout = exports.Layout || (exports.Layout = {}));
	exports.Layout = Layout;
	/**
	 * An object which assists in the absolute layout of widgets.
	 *
	 * #### Notes
	 * This class is useful when implementing a layout which arranges its
	 * widgets using absolute positioning.
	 *
	 * This class is used by nearly all of the built-in Phosphor layouts.
	 */
	var LayoutItem = (function () {
	    /**
	     * Construct a new layout item.
	     *
	     * @param widget - The widget to be managed by the item.
	     *
	     * #### Notes
	     * The widget will be set to absolute positioning.
	     */
	    function LayoutItem(widget) {
	        this._top = NaN;
	        this._left = NaN;
	        this._width = NaN;
	        this._height = NaN;
	        this._minWidth = 0;
	        this._minHeight = 0;
	        this._maxWidth = Infinity;
	        this._maxHeight = Infinity;
	        this._disposed = false;
	        this.widget = widget;
	        this.widget.node.style.position = 'absolute';
	    }
	    /**
	     * Dispose of the the layout item.
	     *
	     * #### Notes
	     * This will reset the positioning of the widget.
	     */
	    LayoutItem.prototype.dispose = function () {
	        // Do nothing if the item is already disposed.
	        if (this._disposed) {
	            return;
	        }
	        // Mark the item as disposed.
	        this._disposed = true;
	        // Reset the widget style.
	        var style = this.widget.node.style;
	        style.position = '';
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	    };
	    Object.defineProperty(LayoutItem.prototype, "minWidth", {
	        /**
	         * The computed minimum width of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._minWidth;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "minHeight", {
	        /**
	         * The computed minimum height of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._minHeight;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "maxWidth", {
	        /**
	         * The computed maximum width of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._maxWidth;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "maxHeight", {
	        /**
	         * The computed maximum height of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._maxHeight;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isDisposed", {
	        /**
	         * Whether the layout item is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isHidden", {
	        /**
	         * Whether the managed widget is hidden.
	         */
	        get: function () {
	            return this.widget.isHidden;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isVisible", {
	        /**
	         * Whether the managed widget is visible.
	         */
	        get: function () {
	            return this.widget.isVisible;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isAttached", {
	        /**
	         * Whether the managed widget is attached.
	         */
	        get: function () {
	            return this.widget.isAttached;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Update the computed size limits of the managed widget.
	     */
	    LayoutItem.prototype.fit = function () {
	        var limits = domutils_1.ElementExt.sizeLimits(this.widget.node);
	        this._minWidth = limits.minWidth;
	        this._minHeight = limits.minHeight;
	        this._maxWidth = limits.maxWidth;
	        this._maxHeight = limits.maxHeight;
	    };
	    /**
	     * Update the position and size of the managed widget.
	     *
	     * @param left - The left edge position of the layout box.
	     *
	     * @param top - The top edge position of the layout box.
	     *
	     * @param width - The width of the layout box.
	     *
	     * @param height - The height of the layout box.
	     */
	    LayoutItem.prototype.update = function (left, top, width, height) {
	        // Clamp the size to the computed size limits.
	        var clampW = Math.max(this._minWidth, Math.min(width, this._maxWidth));
	        var clampH = Math.max(this._minHeight, Math.min(height, this._maxHeight));
	        // Ajdust the left edge for the horizontal alignment, if needed.
	        if (clampW < width) {
	            switch (Layout.getHorizontalAlignment(this.widget)) {
	                case 'left':
	                    break;
	                case 'center':
	                    left += (width - clampW) / 2;
	                    break;
	                case 'right':
	                    left += width - clampW;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Ajdust the top edge for the vertical alignment, if needed.
	        if (clampH < height) {
	            switch (Layout.getVerticalAlignment(this.widget)) {
	                case 'top':
	                    break;
	                case 'center':
	                    top += (height - clampH) / 2;
	                    break;
	                case 'bottom':
	                    top += height - clampH;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Set up the resize variables.
	        var resized = false;
	        var style = this.widget.node.style;
	        // Update the top edge of the widget if needed.
	        if (this._top !== top) {
	            this._top = top;
	            style.top = top + "px";
	        }
	        // Update the left edge of the widget if needed.
	        if (this._left !== left) {
	            this._left = left;
	            style.left = left + "px";
	        }
	        // Update the width of the widget if needed.
	        if (this._width !== clampW) {
	            resized = true;
	            this._width = clampW;
	            style.width = clampW + "px";
	        }
	        // Update the height of the widget if needed.
	        if (this._height !== clampH) {
	            resized = true;
	            this._height = clampH;
	            style.height = clampH + "px";
	        }
	        // Send a resize message to the widget if needed.
	        if (resized) {
	            var msg = new widget_1.Widget.ResizeMessage(clampW, clampH);
	            messaging_1.MessageLoop.sendMessage(this.widget, msg);
	        }
	    };
	    return LayoutItem;
	}());
	exports.LayoutItem = LayoutItem;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The attached property for a widget horizontal alignment.
	     */
	    Private.horizontalAlignmentProperty = new properties_1.AttachedProperty({
	        name: 'horizontalAlignment',
	        create: function () { return 'center'; },
	        changed: onAlignmentChanged
	    });
	    /**
	     * The attached property for a widget vertical alignment.
	     */
	    Private.verticalAlignmentProperty = new properties_1.AttachedProperty({
	        name: 'verticalAlignment',
	        create: function () { return 'top'; },
	        changed: onAlignmentChanged
	    });
	    /**
	     * The change handler for the attached alignment properties.
	     */
	    function onAlignmentChanged(child) {
	        if (child.parent && child.parent.layout) {
	            child.parent.update();
	        }
	    }
	})(Private || (Private = {}));


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

	/* WEBPACK VAR INJECTION */(function(setImmediate) {"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	/**
	 * A concrete implementation of `ISignal`.
	 *
	 * #### Example
	 * ```typescript
	 * import { ISignal, Signal } from '@phosphor/signaling';
	 *
	 * class SomeClass {
	 *
	 *   constructor(name: string) {
	 *     this.name = name;
	 *   }
	 *
	 *   readonly name: string;
	 *
	 *   get valueChanged: ISignal<this, number> {
	 *     return this._valueChanged;
	 *   }
	 *
	 *   get value(): number {
	 *     return this._value;
	 *   }
	 *
	 *   set value(value: number) {
	 *     if (value === this._value) {
	 *       return;
	 *     }
	 *     this._value = value;
	 *     this._valueChanged.emit(value);
	 *   }
	 *
	 *   private _value = 0;
	 *   private _valueChanged = new Signal<this, number>(this);
	 * }
	 *
	 * function logger(sender: SomeClass, value: number): void {
	 *   console.log(sender.name, value);
	 * }
	 *
	 * let m1 = new SomeClass('foo');
	 * let m2 = new SomeClass('bar');
	 *
	 * m1.valueChanged.connect(logger);
	 * m2.valueChanged.connect(logger);
	 *
	 * m1.value = 42;  // logs: foo 42
	 * m2.value = 17;  // logs: bar 17
	 * ```
	 */
	var Signal = (function () {
	    /**
	     * Construct a new signal.
	     *
	     * @param sender - The sender which owns the signal.
	     */
	    function Signal(sender) {
	        this.sender = sender;
	    }
	    /**
	     * Connect a slot to the signal.
	     *
	     * @param slot - The slot to invoke when the signal is emitted.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection succeeds, `false` otherwise.
	     */
	    Signal.prototype.connect = function (slot, thisArg) {
	        return Private.connect(this, slot, thisArg);
	    };
	    /**
	     * Disconnect a slot from the signal.
	     *
	     * @param slot - The slot to disconnect from the signal.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection is removed, `false` otherwise.
	     */
	    Signal.prototype.disconnect = function (slot, thisArg) {
	        return Private.disconnect(this, slot, thisArg);
	    };
	    /**
	     * Emit the signal and invoke the connected slots.
	     *
	     * @param args - The args to pass to the connected slots.
	     *
	     * #### Notes
	     * Slots are invoked synchronously in connection order.
	     *
	     * Exceptions thrown by connected slots will be caught and logged.
	     */
	    Signal.prototype.emit = function (args) {
	        Private.emit(this, args);
	    };
	    return Signal;
	}());
	exports.Signal = Signal;
	/**
	 * The namespace for the `Signal` class statics.
	 */
	(function (Signal) {
	    /**
	     * Remove all connections between a sender and receiver.
	     *
	     * @param sender - The sender object of interest.
	     *
	     * @param receiver - The receiver object of interest.
	     *
	     * #### Notes
	     * If a `thisArg` is provided when connecting a signal, that object
	     * is considered the receiver. Otherwise, the `slot` is considered
	     * the receiver.
	     */
	    function disconnectBetween(sender, receiver) {
	        Private.disconnectBetween(sender, receiver);
	    }
	    Signal.disconnectBetween = disconnectBetween;
	    /**
	     * Remove all connections where the given object is the sender.
	     *
	     * @param sender - The sender object of interest.
	     */
	    function disconnectSender(sender) {
	        Private.disconnectSender(sender);
	    }
	    Signal.disconnectSender = disconnectSender;
	    /**
	     * Remove all connections where the given object is the receiver.
	     *
	     * @param receiver - The receiver object of interest.
	     *
	     * #### Notes
	     * If a `thisArg` is provided when connecting a signal, that object
	     * is considered the receiver. Otherwise, the `slot` is considered
	     * the receiver.
	     */
	    function disconnectReceiver(receiver) {
	        Private.disconnectReceiver(receiver);
	    }
	    Signal.disconnectReceiver = disconnectReceiver;
	    /**
	     * Remove all connections where an object is the sender or receiver.
	     *
	     * @param object - The object of interest.
	     *
	     * #### Notes
	     * If a `thisArg` is provided when connecting a signal, that object
	     * is considered the receiver. Otherwise, the `slot` is considered
	     * the receiver.
	     */
	    function disconnectAll(object) {
	        Private.disconnectAll(object);
	    }
	    Signal.disconnectAll = disconnectAll;
	    /**
	     * Clear all signal data associated with the given object.
	     *
	     * @param object - The object for which the data should be cleared.
	     *
	     * #### Notes
	     * This removes all signal connections and any other signal data
	     * associated with the object.
	     */
	    function clearData(object) {
	        Private.disconnectAll(object);
	    }
	    Signal.clearData = clearData;
	    /**
	     * Get the signal exception handler.
	     *
	     * @returns The current exception handler.
	     *
	     * #### Notes
	     * The default exception handler is `console.error`.
	     */
	    function getExceptionHandler() {
	        return Private.exceptionHandler;
	    }
	    Signal.getExceptionHandler = getExceptionHandler;
	    /**
	     * Set the signal exception handler.
	     *
	     * @param handler - The function to use as the exception handler.
	     *
	     * @returns The old exception handler.
	     *
	     * #### Notes
	     * The exception handler is invoked when a slot throws an exception.
	     */
	    function setExceptionHandler(handler) {
	        var old = Private.exceptionHandler;
	        Private.exceptionHandler = handler;
	        return old;
	    }
	    Signal.setExceptionHandler = setExceptionHandler;
	})(Signal = exports.Signal || (exports.Signal = {}));
	exports.Signal = Signal;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The signal exception handler function.
	     */
	    Private.exceptionHandler = function (err) {
	        console.error(err);
	    };
	    /**
	     * Connect a slot to a signal.
	     *
	     * @param signal - The signal of interest.
	     *
	     * @param slot - The slot to invoke when the signal is emitted.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection succeeds, `false` otherwise.
	     */
	    function connect(signal, slot, thisArg) {
	        // Coerce a `null` `thisArg` to `undefined`.
	        thisArg = thisArg || undefined;
	        // Ensure the sender's array of receivers is created.
	        var receivers = receiversForSender.get(signal.sender);
	        if (!receivers) {
	            receivers = [];
	            receiversForSender.set(signal.sender, receivers);
	        }
	        // Bail if a matching connection already exists.
	        if (findConnection(receivers, signal, slot, thisArg)) {
	            return false;
	        }
	        // Choose the best object for the receiver.
	        var receiver = thisArg || slot;
	        // Ensure the receiver's array of senders is created.
	        var senders = sendersForReceiver.get(receiver);
	        if (!senders) {
	            senders = [];
	            sendersForReceiver.set(receiver, senders);
	        }
	        // Create a new connection and add it to the end of each array.
	        var connection = { signal: signal, slot: slot, thisArg: thisArg };
	        receivers.push(connection);
	        senders.push(connection);
	        // Indicate a successful connection.
	        return true;
	    }
	    Private.connect = connect;
	    /**
	     * Disconnect a slot from a signal.
	     *
	     * @param signal - The signal of interest.
	     *
	     * @param slot - The slot to disconnect from the signal.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection is removed, `false` otherwise.
	     */
	    function disconnect(signal, slot, thisArg) {
	        // Coerce a `null` `thisArg` to `undefined`.
	        thisArg = thisArg || undefined;
	        // Lookup the list of receivers, and bail if none exist.
	        var receivers = receiversForSender.get(signal.sender);
	        if (!receivers || receivers.length === 0) {
	            return false;
	        }
	        // Bail if no matching connection exits.
	        var connection = findConnection(receivers, signal, slot, thisArg);
	        if (!connection) {
	            return false;
	        }
	        // Choose the best object for the receiver.
	        var receiver = thisArg || slot;
	        // Lookup the array of senders, which is now known to exist.
	        var senders = sendersForReceiver.get(receiver);
	        // Clear the connection and schedule cleanup of the arrays.
	        connection.signal = null;
	        scheduleCleanup(receivers);
	        scheduleCleanup(senders);
	        // Indicate a successful disconnection.
	        return true;
	    }
	    Private.disconnect = disconnect;
	    /**
	     * Remove all connections between a sender and receiver.
	     *
	     * @param sender - The sender object of interest.
	     *
	     * @param receiver - The receiver object of interest.
	     */
	    function disconnectBetween(sender, receiver) {
	        // If there are no receivers, there is nothing to do.
	        var receivers = receiversForSender.get(sender);
	        if (!receivers || receivers.length === 0) {
	            return;
	        }
	        // If there are no senders, there is nothing to do.
	        var senders = sendersForReceiver.get(receiver);
	        if (!senders || senders.length === 0) {
	            return;
	        }
	        // Clear each connection between the sender and receiver.
	        algorithm_1.each(senders, function (connection) {
	            // Skip connections which have already been cleared.
	            if (!connection.signal) {
	                return;
	            }
	            // Clear the connection if it matches the sender.
	            if (connection.signal.sender === sender) {
	                connection.signal = null;
	            }
	        });
	        // Schedule a cleanup of the senders and receivers.
	        scheduleCleanup(receivers);
	        scheduleCleanup(senders);
	    }
	    Private.disconnectBetween = disconnectBetween;
	    /**
	     * Remove all connections where the given object is the sender.
	     *
	     * @param sender - The sender object of interest.
	     */
	    function disconnectSender(sender) {
	        // If there are no receivers, there is nothing to do.
	        var receivers = receiversForSender.get(sender);
	        if (!receivers || receivers.length === 0) {
	            return;
	        }
	        // Clear each receiver connection.
	        algorithm_1.each(receivers, function (connection) {
	            // Skip connections which have already been cleared.
	            if (!connection.signal) {
	                return;
	            }
	            // Choose the best object for the receiver.
	            var receiver = connection.thisArg || connection.slot;
	            // Clear the connection.
	            connection.signal = null;
	            // Cleanup the array of senders, which is now known to exist.
	            scheduleCleanup(sendersForReceiver.get(receiver));
	        });
	        // Schedule a cleanup of the receivers.
	        scheduleCleanup(receivers);
	    }
	    Private.disconnectSender = disconnectSender;
	    /**
	     * Remove all connections where the given object is the receiver.
	     *
	     * @param receiver - The receiver object of interest.
	     */
	    function disconnectReceiver(receiver) {
	        // If there are no senders, there is nothing to do.
	        var senders = sendersForReceiver.get(receiver);
	        if (!senders || senders.length === 0) {
	            return;
	        }
	        // Clear each sender connection.
	        algorithm_1.each(senders, function (connection) {
	            // Skip connections which have already been cleared.
	            if (!connection.signal) {
	                return;
	            }
	            // Lookup the sender for the connection.
	            var sender = connection.signal.sender;
	            // Clear the connection.
	            connection.signal = null;
	            // Cleanup the array of receivers, which is now known to exist.
	            scheduleCleanup(receiversForSender.get(sender));
	        });
	        // Schedule a cleanup of the list of senders.
	        scheduleCleanup(senders);
	    }
	    Private.disconnectReceiver = disconnectReceiver;
	    /**
	     * Remove all connections where an object is the sender or receiver.
	     *
	     * @param object - The object of interest.
	     */
	    function disconnectAll(object) {
	        // Clear and cleanup any receiver connections.
	        var receivers = receiversForSender.get(object);
	        if (receivers && receivers.length > 0) {
	            algorithm_1.each(receivers, function (connection) { connection.signal = null; });
	            scheduleCleanup(receivers);
	        }
	        // Clear and cleanup any sender connections.
	        var senders = sendersForReceiver.get(object);
	        if (senders && senders.length > 0) {
	            algorithm_1.each(senders, function (connection) { connection.signal = null; });
	            scheduleCleanup(senders);
	        }
	    }
	    Private.disconnectAll = disconnectAll;
	    /**
	     * Emit a signal and invoke its connected slots.
	     *
	     * @param signal - The signal of interest.
	     *
	     * @param args - The args to pass to the connected slots.
	     *
	     * #### Notes
	     * Slots are invoked synchronously in connection order.
	     *
	     * Exceptions thrown by connected slots will be caught and logged.
	     */
	    function emit(signal, args) {
	        // If there are no receivers, there is nothing to do.
	        var receivers = receiversForSender.get(signal.sender);
	        if (!receivers || receivers.length === 0) {
	            return;
	        }
	        // Invoke the slots for connections with a matching signal.
	        // Any connections added during emission are not invoked.
	        for (var i = 0, n = receivers.length; i < n; ++i) {
	            var connection = receivers[i];
	            if (connection.signal === signal) {
	                invokeSlot(connection, args);
	            }
	        }
	    }
	    Private.emit = emit;
	    /**
	     * A weak mapping of sender to array of receiver connections.
	     */
	    var receiversForSender = new WeakMap();
	    /**
	     * A weak mapping of receiver to array of sender connections.
	     */
	    var sendersForReceiver = new WeakMap();
	    /**
	     * A set of connection arrays which are pending cleanup.
	     */
	    var dirtySet = new Set();
	    /**
	     * A function to schedule an event loop callback.
	     */
	    var schedule = (function () {
	        var ok = typeof requestAnimationFrame === 'function';
	        return ok ? requestAnimationFrame : setImmediate;
	    })();
	    /**
	     * Find a connection which matches the given parameters.
	     */
	    function findConnection(connections, signal, slot, thisArg) {
	        return algorithm_1.find(connections, function (connection) { return (connection.signal === signal &&
	            connection.slot === slot &&
	            connection.thisArg === thisArg); });
	    }
	    /**
	     * Invoke a slot with the given parameters.
	     *
	     * The connection is assumed to be valid.
	     *
	     * Exceptions in the slot will be caught and logged.
	     */
	    function invokeSlot(connection, args) {
	        var signal = connection.signal, slot = connection.slot, thisArg = connection.thisArg;
	        try {
	            slot.call(thisArg, signal.sender, args);
	        }
	        catch (err) {
	            Private.exceptionHandler(err);
	        }
	    }
	    /**
	     * Schedule a cleanup of a connection array.
	     *
	     * This will add the array to the dirty set and schedule a deferred
	     * cleanup of the array contents. On cleanup, any connection with a
	     * `null` signal will be removed from the array.
	     */
	    function scheduleCleanup(array) {
	        if (dirtySet.size === 0) {
	            schedule(cleanupDirtySet);
	        }
	        dirtySet.add(array);
	    }
	    /**
	     * Cleanup the connection lists in the dirty set.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupDirtySet() {
	        dirtySet.forEach(cleanupConnections);
	        dirtySet.clear();
	    }
	    /**
	     * Cleanup the dirty connections in a connections array.
	     *
	     * This will remove any connection with a `null` signal.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupConnections(connections) {
	        algorithm_1.ArrayExt.removeAllWhere(connections, isDeadConnection);
	    }
	    /**
	     * Test whether a connection is dead.
	     *
	     * A dead connection has a `null` signal.
	     */
	    function isDeadConnection(connection) {
	        return connection.signal === null;
	    }
	})(Private || (Private = {}));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(51).setImmediate))

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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var messaging_1 = __webpack_require__(196);
	var properties_1 = __webpack_require__(199);
	var signaling_1 = __webpack_require__(201);
	var title_1 = __webpack_require__(203);
	/**
	 * The base class of the Phosphor widget hierarchy.
	 *
	 * #### Notes
	 * This class will typically be subclassed in order to create a useful
	 * widget. However, it can be used directly to host externally created
	 * content.
	 */
	var Widget = (function () {
	    /**
	     * Construct a new widget.
	     *
	     * @param options - The options for initializing the widget.
	     */
	    function Widget(options) {
	        if (options === void 0) { options = {}; }
	        this._flags = 0;
	        this._layout = null;
	        this._parent = null;
	        this._disposed = new signaling_1.Signal(this);
	        this.node = Private.createNode(options);
	        this.addClass('p-Widget');
	    }
	    /**
	     * Dispose of the widget and its descendant widgets.
	     *
	     * #### Notes
	     * It is unsafe to use the widget after it has been disposed.
	     *
	     * All calls made to this method after the first are a no-op.
	     */
	    Widget.prototype.dispose = function () {
	        // Do nothing if the widget is already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        // Set the disposed flag and emit the disposed signal.
	        this.setFlag(Widget.Flag.IsDisposed);
	        this._disposed.emit(undefined);
	        // Remove or detach the widget if necessary.
	        if (this.parent) {
	            this.parent = null;
	        }
	        else if (this.isAttached) {
	            Widget.detach(this);
	        }
	        // Dispose of the widget layout.
	        if (this._layout) {
	            this._layout.dispose();
	            this._layout = null;
	        }
	        // Clear the extra data associated with the widget.
	        signaling_1.Signal.clearData(this);
	        messaging_1.MessageLoop.clearData(this);
	        properties_1.AttachedProperty.clearData(this);
	    };
	    Object.defineProperty(Widget.prototype, "disposed", {
	        /**
	         * A signal emitted when the widget is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isDisposed", {
	        /**
	         * Test whether the widget has been disposed.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsDisposed);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isAttached", {
	        /**
	         * Test whether the widget's node is attached to the DOM.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsAttached);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isHidden", {
	        /**
	         * Test whether the widget is explicitly hidden.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsHidden);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isVisible", {
	        /**
	         * Test whether the widget is visible.
	         *
	         * #### Notes
	         * A widget is visible when it is attached to the DOM, is not
	         * explicitly hidden, and has no explicitly hidden ancestors.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsVisible);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "title", {
	        /**
	         * The title object for the widget.
	         *
	         * #### Notes
	         * The title object is used by some container widgets when displaying
	         * the widget alongside some title, such as a tab panel or side bar.
	         *
	         * Since not all widgets will use the title, it is created on demand.
	         *
	         * The `owner` property of the title is set to this widget.
	         */
	        get: function () {
	            return Private.titleProperty.get(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "id", {
	        /**
	         * Get the id of the widget's DOM node.
	         */
	        get: function () {
	            return this.node.id;
	        },
	        /**
	         * Set the id of the widget's DOM node.
	         */
	        set: function (value) {
	            this.node.id = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "dataset", {
	        /**
	         * The dataset for the widget's DOM node.
	         */
	        get: function () {
	            return this.node.dataset;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "parent", {
	        /**
	         * Get the parent of the widget.
	         */
	        get: function () {
	            return this._parent;
	        },
	        /**
	         * Set the parent of the widget.
	         *
	         * #### Notes
	         * Children are typically added to a widget by using a layout, which
	         * means user code will not normally set the parent widget directly.
	         *
	         * The widget will be automatically removed from its old parent.
	         *
	         * This is a no-op if there is no effective parent change.
	         */
	        set: function (value) {
	            if (this._parent === value) {
	                return;
	            }
	            if (value && this.contains(value)) {
	                throw new Error('Invalid parent widget.');
	            }
	            if (this._parent && !this._parent.isDisposed) {
	                var msg = new Widget.ChildMessage('child-removed', this);
	                messaging_1.MessageLoop.sendMessage(this._parent, msg);
	            }
	            this._parent = value;
	            if (this._parent && !this._parent.isDisposed) {
	                var msg = new Widget.ChildMessage('child-added', this);
	                messaging_1.MessageLoop.sendMessage(this._parent, msg);
	            }
	            if (!this.isDisposed) {
	                messaging_1.MessageLoop.sendMessage(this, Widget.Msg.ParentChanged);
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "layout", {
	        /**
	         * Get the layout for the widget.
	         */
	        get: function () {
	            return this._layout;
	        },
	        /**
	         * Set the layout for the widget.
	         *
	         * #### Notes
	         * The layout is single-use only. It cannot be changed after the
	         * first assignment.
	         *
	         * The layout is disposed automatically when the widget is disposed.
	         */
	        set: function (value) {
	            if (this._layout === value) {
	                return;
	            }
	            if (this.testFlag(Widget.Flag.DisallowLayout)) {
	                throw new Error('Cannot set widget layout.');
	            }
	            if (this._layout) {
	                throw new Error('Cannot change widget layout.');
	            }
	            if (value.parent) {
	                throw new Error('Cannot change layout parent.');
	            }
	            this._layout = value;
	            value.parent = this;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the widget's children.
	     *
	     * @returns A new iterator over the children of the widget.
	     *
	     * #### Notes
	     * The widget must have a populated layout in order to have children.
	     *
	     * If a layout is not installed, the returned iterator will be empty.
	     */
	    Widget.prototype.children = function () {
	        return this._layout ? this._layout.iter() : algorithm_1.empty();
	    };
	    /**
	     * Test whether a widget is a descendant of this widget.
	     *
	     * @param widget - The descendant widget of interest.
	     *
	     * @returns `true` if the widget is a descendant, `false` otherwise.
	     */
	    Widget.prototype.contains = function (widget) {
	        for (var value = widget; value; value = value._parent) {
	            if (value === this) {
	                return true;
	            }
	        }
	        return false;
	    };
	    /**
	     * Test whether the widget's DOM node has the given class name.
	     *
	     * @param name - The class name of interest.
	     *
	     * @returns `true` if the node has the class, `false` otherwise.
	     */
	    Widget.prototype.hasClass = function (name) {
	        return this.node.classList.contains(name);
	    };
	    /**
	     * Add a class name to the widget's DOM node.
	     *
	     * @param name - The class name to add to the node.
	     *
	     * #### Notes
	     * If the class name is already added to the node, this is a no-op.
	     *
	     * The class name must not contain whitespace.
	     */
	    Widget.prototype.addClass = function (name) {
	        this.node.classList.add(name);
	    };
	    /**
	     * Remove a class name from the widget's DOM node.
	     *
	     * @param name - The class name to remove from the node.
	     *
	     * #### Notes
	     * If the class name is not yet added to the node, this is a no-op.
	     *
	     * The class name must not contain whitespace.
	     */
	    Widget.prototype.removeClass = function (name) {
	        this.node.classList.remove(name);
	    };
	    /**
	     * Toggle a class name on the widget's DOM node.
	     *
	     * @param name - The class name to toggle on the node.
	     *
	     * @param force - Whether to force add the class (`true`) or force
	     *   remove the class (`false`). If not provided, the presence of
	     *   the class will be toggled from its current state.
	     *
	     * @returns `true` if the class is now present, `false` otherwise.
	     *
	     * #### Notes
	     * The class name must not contain whitespace.
	     */
	    Widget.prototype.toggleClass = function (name, force) {
	        if (force === true) {
	            this.node.classList.add(name);
	            return true;
	        }
	        if (force === false) {
	            this.node.classList.remove(name);
	            return false;
	        }
	        return this.node.classList.toggle(name);
	    };
	    /**
	     * Post an `'update-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for posting the message.
	     */
	    Widget.prototype.update = function () {
	        messaging_1.MessageLoop.postMessage(this, Widget.Msg.UpdateRequest);
	    };
	    /**
	     * Post a `'fit-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for posting the message.
	     */
	    Widget.prototype.fit = function () {
	        messaging_1.MessageLoop.postMessage(this, Widget.Msg.FitRequest);
	    };
	    /**
	     * Post an `'activate-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for posting the message.
	     */
	    Widget.prototype.activate = function () {
	        messaging_1.MessageLoop.postMessage(this, Widget.Msg.ActivateRequest);
	    };
	    /**
	     * Send a `'close-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for sending the message.
	     */
	    Widget.prototype.close = function () {
	        messaging_1.MessageLoop.sendMessage(this, Widget.Msg.CloseRequest);
	    };
	    /**
	     * Show the widget and make it visible to its parent widget.
	     *
	     * #### Notes
	     * This causes the [[isHidden]] property to be `false`.
	     *
	     * If the widget is not explicitly hidden, this is a no-op.
	     */
	    Widget.prototype.show = function () {
	        if (!this.testFlag(Widget.Flag.IsHidden)) {
	            return;
	        }
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.BeforeShow);
	        }
	        this.clearFlag(Widget.Flag.IsHidden);
	        this.removeClass('p-mod-hidden');
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.AfterShow);
	        }
	        if (this.parent) {
	            var msg = new Widget.ChildMessage('child-shown', this);
	            messaging_1.MessageLoop.sendMessage(this.parent, msg);
	        }
	    };
	    /**
	     * Hide the widget and make it hidden to its parent widget.
	     *
	     * #### Notes
	     * This causes the [[isHidden]] property to be `true`.
	     *
	     * If the widget is explicitly hidden, this is a no-op.
	     */
	    Widget.prototype.hide = function () {
	        if (this.testFlag(Widget.Flag.IsHidden)) {
	            return;
	        }
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.BeforeHide);
	        }
	        this.setFlag(Widget.Flag.IsHidden);
	        this.addClass('p-mod-hidden');
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.AfterHide);
	        }
	        if (this.parent) {
	            var msg = new Widget.ChildMessage('child-hidden', this);
	            messaging_1.MessageLoop.sendMessage(this.parent, msg);
	        }
	    };
	    /**
	     * Show or hide the widget according to a boolean value.
	     *
	     * @param hidden - `true` to hide the widget, or `false` to show it.
	     *
	     * #### Notes
	     * This is a convenience method for `hide()` and `show()`.
	     */
	    Widget.prototype.setHidden = function (hidden) {
	        if (hidden) {
	            this.hide();
	        }
	        else {
	            this.show();
	        }
	    };
	    /**
	     * Test whether the given widget flag is set.
	     *
	     * #### Notes
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.testFlag = function (flag) {
	        return (this._flags & flag) !== 0;
	    };
	    /**
	     * Set the given widget flag.
	     *
	     * #### Notes
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.setFlag = function (flag) {
	        this._flags |= flag;
	    };
	    /**
	     * Clear the given widget flag.
	     *
	     * #### Notes
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.clearFlag = function (flag) {
	        this._flags &= ~flag;
	    };
	    /**
	     * Process a message sent to the widget.
	     *
	     * @param msg - The message sent to the widget.
	     *
	     * #### Notes
	     * Subclasses may reimplement this method as needed.
	     */
	    Widget.prototype.processMessage = function (msg) {
	        switch (msg.type) {
	            case 'resize':
	                this.notifyLayout(msg);
	                this.onResize(msg);
	                break;
	            case 'update-request':
	                this.notifyLayout(msg);
	                this.onUpdateRequest(msg);
	                break;
	            case 'fit-request':
	                this.notifyLayout(msg);
	                this.onFitRequest(msg);
	                break;
	            case 'before-show':
	                this.notifyLayout(msg);
	                this.onBeforeShow(msg);
	                break;
	            case 'after-show':
	                this.setFlag(Widget.Flag.IsVisible);
	                this.notifyLayout(msg);
	                this.onAfterShow(msg);
	                break;
	            case 'before-hide':
	                this.notifyLayout(msg);
	                this.onBeforeHide(msg);
	                break;
	            case 'after-hide':
	                this.clearFlag(Widget.Flag.IsVisible);
	                this.notifyLayout(msg);
	                this.onAfterHide(msg);
	                break;
	            case 'before-attach':
	                this.notifyLayout(msg);
	                this.onBeforeAttach(msg);
	                break;
	            case 'after-attach':
	                if (!this.isHidden && (!this.parent || this.parent.isVisible)) {
	                    this.setFlag(Widget.Flag.IsVisible);
	                }
	                this.setFlag(Widget.Flag.IsAttached);
	                this.notifyLayout(msg);
	                this.onAfterAttach(msg);
	                break;
	            case 'before-detach':
	                this.notifyLayout(msg);
	                this.onBeforeDetach(msg);
	                break;
	            case 'after-detach':
	                this.clearFlag(Widget.Flag.IsVisible);
	                this.clearFlag(Widget.Flag.IsAttached);
	                this.notifyLayout(msg);
	                this.onAfterDetach(msg);
	                break;
	            case 'activate-request':
	                this.notifyLayout(msg);
	                this.onActivateRequest(msg);
	                break;
	            case 'close-request':
	                this.notifyLayout(msg);
	                this.onCloseRequest(msg);
	                break;
	            case 'child-added':
	                this.notifyLayout(msg);
	                this.onChildAdded(msg);
	                break;
	            case 'child-removed':
	                this.notifyLayout(msg);
	                this.onChildRemoved(msg);
	                break;
	            default:
	                this.notifyLayout(msg);
	                break;
	        }
	    };
	    /**
	     * Invoke the message processing routine of the widget's layout.
	     *
	     * @param msg - The message to dispatch to the layout.
	     *
	     * #### Notes
	     * This is a no-op if the widget does not have a layout.
	     *
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.notifyLayout = function (msg) {
	        if (this._layout) {
	            this._layout.processParentMessage(msg);
	        }
	    };
	    /**
	     * A message handler invoked on a `'close-request'` message.
	     *
	     * #### Notes
	     * The default implementation unparents or detaches the widget.
	     */
	    Widget.prototype.onCloseRequest = function (msg) {
	        if (this.parent) {
	            this.parent = null;
	        }
	        else if (this.isAttached) {
	            Widget.detach(this);
	        }
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onResize = function (msg) { };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onUpdateRequest = function (msg) { };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onFitRequest = function (msg) { };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onActivateRequest = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeShow = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterShow = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeHide = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterHide = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeAttach = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterAttach = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeDetach = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterDetach = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onChildAdded = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onChildRemoved = function (msg) { };
	    return Widget;
	}());
	exports.Widget = Widget;
	/**
	 * The namespace for the `Widget` class statics.
	 */
	(function (Widget) {
	    /**
	     * An enum of widget bit flags.
	     */
	    var Flag;
	    (function (Flag) {
	        /**
	         * The widget has been disposed.
	         */
	        Flag[Flag["IsDisposed"] = 1] = "IsDisposed";
	        /**
	         * The widget is attached to the DOM.
	         */
	        Flag[Flag["IsAttached"] = 2] = "IsAttached";
	        /**
	         * The widget is hidden.
	         */
	        Flag[Flag["IsHidden"] = 4] = "IsHidden";
	        /**
	         * The widget is visible.
	         */
	        Flag[Flag["IsVisible"] = 8] = "IsVisible";
	        /**
	         * A layout cannot be set on the widget.
	         */
	        Flag[Flag["DisallowLayout"] = 16] = "DisallowLayout";
	    })(Flag = Widget.Flag || (Widget.Flag = {}));
	    /**
	     * A collection of stateless messages related to widgets.
	     */
	    var Msg;
	    (function (Msg) {
	        /**
	         * A singleton `'before-show'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it becomes visible.
	         *
	         * This message is **not** sent when the widget is being attached.
	         */
	        Msg.BeforeShow = new messaging_1.Message('before-show');
	        /**
	         * A singleton `'after-show'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it becomes visible.
	         *
	         * This message is **not** sent when the widget is being attached.
	         */
	        Msg.AfterShow = new messaging_1.Message('after-show');
	        /**
	         * A singleton `'before-hide'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it becomes not-visible.
	         *
	         * This message is **not** sent when the widget is being detached.
	         */
	        Msg.BeforeHide = new messaging_1.Message('before-hide');
	        /**
	         * A singleton `'after-hide'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it becomes not-visible.
	         *
	         * This message is **not** sent when the widget is being detached.
	         */
	        Msg.AfterHide = new messaging_1.Message('after-hide');
	        /**
	         * A singleton `'before-attach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it is attached.
	         */
	        Msg.BeforeAttach = new messaging_1.Message('before-attach');
	        /**
	         * A singleton `'after-attach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it is attached.
	         */
	        Msg.AfterAttach = new messaging_1.Message('after-attach');
	        /**
	         * A singleton `'before-detach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it is detached.
	         */
	        Msg.BeforeDetach = new messaging_1.Message('before-detach');
	        /**
	         * A singleton `'after-detach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it is detached.
	         */
	        Msg.AfterDetach = new messaging_1.Message('after-detach');
	        /**
	         * A singleton `'parent-changed'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget when its parent has changed.
	         */
	        Msg.ParentChanged = new messaging_1.Message('parent-changed');
	        /**
	         * A singleton conflatable `'update-request'` message.
	         *
	         * #### Notes
	         * This message can be dispatched to supporting widgets in order to
	         * update their content based on the current widget state. Not all
	         * widgets will respond to messages of this type.
	         *
	         * For widgets with a layout, this message will inform the layout to
	         * update the position and size of its child widgets.
	         */
	        Msg.UpdateRequest = new messaging_1.ConflatableMessage('update-request');
	        /**
	         * A singleton conflatable `'fit-request'` message.
	         *
	         * #### Notes
	         * For widgets with a layout, this message will inform the layout to
	         * recalculate its size constraints to fit the space requirements of
	         * its child widgets, and to update their position and size. Not all
	         * layouts will respond to messages of this type.
	         */
	        Msg.FitRequest = new messaging_1.ConflatableMessage('fit-request');
	        /**
	         * A singleton conflatable `'activate-request'` message.
	         *
	         * #### Notes
	         * This message should be dispatched to a widget when it should
	         * perform the actions necessary to activate the widget, which
	         * may include focusing its node or descendant node.
	         */
	        Msg.ActivateRequest = new messaging_1.ConflatableMessage('activate-request');
	        /**
	         * A singleton conflatable `'close-request'` message.
	         *
	         * #### Notes
	         * This message should be dispatched to a widget when it should close
	         * and remove itself from the widget hierarchy.
	         */
	        Msg.CloseRequest = new messaging_1.ConflatableMessage('close-request');
	    })(Msg = Widget.Msg || (Widget.Msg = {}));
	    /**
	     * A message class for child related messages.
	     */
	    var ChildMessage = (function (_super) {
	        __extends(ChildMessage, _super);
	        /**
	         * Construct a new child message.
	         *
	         * @param type - The message type.
	         *
	         * @param child - The child widget for the message.
	         */
	        function ChildMessage(type, child) {
	            var _this = _super.call(this, type) || this;
	            _this.child = child;
	            return _this;
	        }
	        return ChildMessage;
	    }(messaging_1.Message));
	    Widget.ChildMessage = ChildMessage;
	    /**
	     * A message class for `'resize'` messages.
	     */
	    var ResizeMessage = (function (_super) {
	        __extends(ResizeMessage, _super);
	        /**
	         * Construct a new resize message.
	         *
	         * @param width - The **offset width** of the widget, or `-1` if
	         *   the width is not known.
	         *
	         * @param height - The **offset height** of the widget, or `-1` if
	         *   the height is not known.
	         */
	        function ResizeMessage(width, height) {
	            var _this = _super.call(this, 'resize') || this;
	            _this.width = width;
	            _this.height = height;
	            return _this;
	        }
	        return ResizeMessage;
	    }(messaging_1.Message));
	    Widget.ResizeMessage = ResizeMessage;
	    /**
	     * The namespace for the `ResizeMessage` class statics.
	     */
	    (function (ResizeMessage) {
	        /**
	         * A singleton `'resize'` message with an unknown size.
	         */
	        ResizeMessage.UnknownSize = new ResizeMessage(-1, -1);
	    })(ResizeMessage = Widget.ResizeMessage || (Widget.ResizeMessage = {}));
	    /**
	     * Attach a widget to a host DOM node.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param host - The DOM node to use as the widget's host.
	     *
	     * @param ref - The child of `host` to use as the reference element.
	     *   If this is provided, the widget will be inserted before this
	     *   node in the host. The default is `null`, which will cause the
	     *   widget to be added as the last child of the host.
	     *
	     * #### Notes
	     * This will throw an error if the widget is not a root widget, if
	     * the widget is already attached, or if the host is not attached
	     * to the DOM.
	     */
	    function attach(widget, host, ref) {
	        if (ref === void 0) { ref = null; }
	        if (widget.parent) {
	            throw new Error('Cannot attach a child widget.');
	        }
	        if (widget.isAttached || document.body.contains(widget.node)) {
	            throw new Error('Widget is already attached.');
	        }
	        if (!document.body.contains(host)) {
	            throw new Error('Host is not attached.');
	        }
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);
	        host.insertBefore(widget.node, ref);
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);
	    }
	    Widget.attach = attach;
	    /**
	     * Detach the widget from its host DOM node.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * This will throw an error if the widget is not a root widget,
	     * or if the widget is not attached to the DOM.
	     */
	    function detach(widget) {
	        if (widget.parent) {
	            throw new Error('Cannot detach a child widget.');
	        }
	        if (!widget.isAttached || !document.body.contains(widget.node)) {
	            throw new Error('Widget is not attached.');
	        }
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);
	        widget.node.parentNode.removeChild(widget.node);
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);
	    }
	    Widget.detach = detach;
	})(Widget = exports.Widget || (exports.Widget = {}));
	exports.Widget = Widget;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * An attached property for the widget title object.
	     */
	    Private.titleProperty = new properties_1.AttachedProperty({
	        name: 'title',
	        create: function (owner) { return new title_1.Title({ owner: owner }); },
	    });
	    /**
	     * Create a DOM node for the given widget options.
	     */
	    function createNode(options) {
	        return options.node || document.createElement('div');
	    }
	    Private.createNode = createNode;
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var signaling_1 = __webpack_require__(201);
	/**
	 * An object which holds data related to an object's title.
	 *
	 * #### Notes
	 * A title object is intended to hold the data necessary to display a
	 * header for a particular object. A common example is the `TabPanel`,
	 * which uses the widget title to populate the tab for a child widget.
	 */
	var Title = (function () {
	    /**
	     * Construct a new title.
	     *
	     * @param options - The options for initializing the title.
	     */
	    function Title(options) {
	        this._label = '';
	        this._caption = '';
	        this._mnemonic = -1;
	        this._iconClass = '';
	        this._iconLabel = '';
	        this._className = '';
	        this._closable = false;
	        this._changed = new signaling_1.Signal(this);
	        this.owner = options.owner;
	        if (options.label !== undefined) {
	            this._label = options.label;
	        }
	        if (options.mnemonic !== undefined) {
	            this._mnemonic = options.mnemonic;
	        }
	        if (options.icon !== undefined) {
	            this._iconClass = options.icon;
	        }
	        if (options.iconClass !== undefined) {
	            this._iconClass = options.iconClass;
	        }
	        if (options.iconLabel !== undefined) {
	            this._iconLabel = options.iconLabel;
	        }
	        if (options.caption !== undefined) {
	            this._caption = options.caption;
	        }
	        if (options.className !== undefined) {
	            this._className = options.className;
	        }
	        if (options.closable !== undefined) {
	            this._closable = options.closable;
	        }
	        this._dataset = options.dataset || {};
	    }
	    Object.defineProperty(Title.prototype, "changed", {
	        /**
	         * A signal emitted when the state of the title changes.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "label", {
	        /**
	         * Get the label for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._label;
	        },
	        /**
	         * Set the label for the title.
	         */
	        set: function (value) {
	            if (this._label === value) {
	                return;
	            }
	            this._label = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "mnemonic", {
	        /**
	         * Get the mnemonic index for the title.
	         *
	         * #### Notes
	         * The default value is `-1`.
	         */
	        get: function () {
	            return this._mnemonic;
	        },
	        /**
	         * Set the mnemonic index for the title.
	         */
	        set: function (value) {
	            if (this._mnemonic === value) {
	                return;
	            }
	            this._mnemonic = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "icon", {
	        /**
	         * @deprecated Use `iconClass` instead.
	         */
	        get: function () {
	            return this.iconClass;
	        },
	        /**
	         * @deprecated Use `iconClass` instead.
	         */
	        set: function (value) {
	            this.iconClass = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "iconClass", {
	        /**
	         * Get the icon class name for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._iconClass;
	        },
	        /**
	         * Set the icon class name for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            if (this._iconClass === value) {
	                return;
	            }
	            this._iconClass = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "iconLabel", {
	        /**
	         * Get the icon label for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._iconLabel;
	        },
	        /**
	         * Set the icon label for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            if (this._iconLabel === value) {
	                return;
	            }
	            this._iconLabel = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "caption", {
	        /**
	         * Get the caption for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._caption;
	        },
	        /**
	         * Set the caption for the title.
	         */
	        set: function (value) {
	            if (this._caption === value) {
	                return;
	            }
	            this._caption = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "className", {
	        /**
	         * Get the extra class name for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._className;
	        },
	        /**
	         * Set the extra class name for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            if (this._className === value) {
	                return;
	            }
	            this._className = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "closable", {
	        /**
	         * Get the closable state for the title.
	         *
	         * #### Notes
	         * The default value is `false`.
	         */
	        get: function () {
	            return this._closable;
	        },
	        /**
	         * Set the closable state for the title.
	         *
	         * #### Notes
	         * This controls the presence of a close icon when applicable.
	         */
	        set: function (value) {
	            if (this._closable === value) {
	                return;
	            }
	            this._closable = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "dataset", {
	        /**
	         * Get the dataset for the title.
	         *
	         * #### Notes
	         * The default value is an empty dataset.
	         */
	        get: function () {
	            return this._dataset;
	        },
	        /**
	         * Set the dataset for the title.
	         *
	         * #### Notes
	         * This controls the data attributes when applicable.
	         */
	        set: function (value) {
	            if (this._dataset === value) {
	                return;
	            }
	            this._dataset = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return Title;
	}());
	exports.Title = Title;


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var messaging_1 = __webpack_require__(196);
	var layout_1 = __webpack_require__(200);
	var widget_1 = __webpack_require__(202);
	/**
	 * A concrete layout implementation suitable for many use cases.
	 *
	 * #### Notes
	 * This class is suitable as a base class for implementing a variety of
	 * layouts, but can also be used directly with standard CSS to layout a
	 * collection of widgets.
	 */
	var PanelLayout = (function (_super) {
	    __extends(PanelLayout, _super);
	    function PanelLayout() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._widgets = [];
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This will clear and dispose all widgets in the layout.
	     *
	     * All reimplementations should call the superclass method.
	     *
	     * This method is called automatically when the parent is disposed.
	     */
	    PanelLayout.prototype.dispose = function () {
	        while (this._widgets.length > 0) {
	            this._widgets.pop().dispose();
	        }
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(PanelLayout.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the layout.
	         */
	        get: function () {
	            return this._widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the widgets in the layout.
	     *
	     * @returns A new iterator over the widgets in the layout.
	     */
	    PanelLayout.prototype.iter = function () {
	        return algorithm_1.iter(this._widgets);
	    };
	    /**
	     * Add a widget to the end of the layout.
	     *
	     * @param widget - The widget to add to the layout.
	     *
	     * #### Notes
	     * If the widget is already contained in the layout, it will be moved.
	     */
	    PanelLayout.prototype.addWidget = function (widget) {
	        this.insertWidget(this._widgets.length, widget);
	    };
	    /**
	     * Insert a widget into the layout at the specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into the layout.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the widgets.
	     *
	     * If the widget is already added to the layout, it will be moved.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    PanelLayout.prototype.insertWidget = function (index, widget) {
	        // Remove the widget from its current parent. This is a no-op
	        // if the widget's parent is already the layout parent widget.
	        widget.parent = this.parent;
	        // Look up the current index of the widget.
	        var i = this._widgets.indexOf(widget);
	        // Clamp the insert index to the array bounds.
	        var j = Math.max(0, Math.min(index, this._widgets.length));
	        // If the widget is not in the array, insert it.
	        if (i === -1) {
	            // Insert the widget into the array.
	            algorithm_1.ArrayExt.insert(this._widgets, j, widget);
	            // If the layout is parented, attach the widget to the DOM.
	            if (this.parent) {
	                this.attachWidget(j, widget);
	            }
	            // There is nothing more to do.
	            return;
	        }
	        // Otherwise, the widget exists in the array and should be moved.
	        // Adjust the index if the location is at the end of the array.
	        if (j === this._widgets.length) {
	            j--;
	        }
	        // Bail if there is no effective move.
	        if (i === j) {
	            return;
	        }
	        // Move the widget to the new location.
	        algorithm_1.ArrayExt.move(this._widgets, i, j);
	        // If the layout is parented, move the widget in the DOM.
	        if (this.parent) {
	            this.moveWidget(i, j, widget);
	        }
	    };
	    /**
	     * Remove a widget from the layout.
	     *
	     * @param widget - The widget to remove from the layout.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     */
	    PanelLayout.prototype.removeWidget = function (widget) {
	        this.removeWidgetAt(this._widgets.indexOf(widget));
	    };
	    /**
	     * Remove the widget at a given index from the layout.
	     *
	     * @param index - The index of the widget to remove.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    PanelLayout.prototype.removeWidgetAt = function (index) {
	        // Remove the widget from the array.
	        var widget = algorithm_1.ArrayExt.removeAt(this._widgets, index);
	        // If the layout is parented, detach the widget from the DOM.
	        if (widget && this.parent) {
	            this.detachWidget(index, widget);
	        }
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    PanelLayout.prototype.init = function () {
	        var _this = this;
	        _super.prototype.init.call(this);
	        algorithm_1.each(this, function (widget, index) {
	            _this.attachWidget(index, widget);
	        });
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This method is called automatically by the panel layout at the
	     * appropriate time. It should not be called directly by user code.
	     *
	     * The default implementation adds the widgets's node to the parent's
	     * node at the proper location, and sends the appropriate attach
	     * messages to the widget if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the widget's
	     * node is added to the parent's node.
	     */
	    PanelLayout.prototype.attachWidget = function (index, widget) {
	        // Look up the next sibling reference node.
	        var ref = this.parent.node.children[index];
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Insert the widget's node before the sibling.
	        this.parent.node.insertBefore(widget.node, ref);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This method is called automatically by the panel layout at the
	     * appropriate time. It should not be called directly by user code.
	     *
	     * The default implementation moves the widget's node to the proper
	     * location in the parent's node and sends the appropriate attach and
	     * detach messages to the widget if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the widget's
	     * node is moved in the parent's node.
	     */
	    PanelLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` and  message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Look up the next sibling reference node.
	        var ref = this.parent.node.children[toIndex];
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Insert the widget's node before the sibling.
	        this.parent.node.insertBefore(widget.node, ref);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This method is called automatically by the panel layout at the
	     * appropriate time. It should not be called directly by user code.
	     *
	     * The default implementation removes the widget's node from the
	     * parent's node, and sends the appropriate detach messages to the
	     * widget if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the widget's
	     * node is removed from the parent's node.
	     */
	    PanelLayout.prototype.detachWidget = function (index, widget) {
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	    };
	    return PanelLayout;
	}(layout_1.Layout));
	exports.PanelLayout = PanelLayout;


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var boxlayout_1 = __webpack_require__(174);
	var panel_1 = __webpack_require__(206);
	/**
	 * A panel which arranges its widgets in a single row or column.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[BoxLayout]].
	 */
	var BoxPanel = (function (_super) {
	    __extends(BoxPanel, _super);
	    /**
	     * Construct a new box panel.
	     *
	     * @param options - The options for initializing the box panel.
	     */
	    function BoxPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { layout: Private.createLayout(options) }) || this;
	        _this.addClass('p-BoxPanel');
	        return _this;
	    }
	    Object.defineProperty(BoxPanel.prototype, "direction", {
	        /**
	         * Get the layout direction for the box panel.
	         */
	        get: function () {
	            return this.layout.direction;
	        },
	        /**
	         * Set the layout direction for the box panel.
	         */
	        set: function (value) {
	            this.layout.direction = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxPanel.prototype, "alignment", {
	        /**
	         * Get the content alignment for the box panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        get: function () {
	            return this.layout.alignment;
	        },
	        /**
	         * Set the content alignment for the box panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        set: function (value) {
	            this.layout.alignment = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxPanel.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the box panel.
	         */
	        get: function () {
	            return this.layout.spacing;
	        },
	        /**
	         * Set the inter-element spacing for the box panel.
	         */
	        set: function (value) {
	            this.layout.spacing = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    BoxPanel.prototype.onChildAdded = function (msg) {
	        msg.child.addClass('p-BoxPanel-child');
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    BoxPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass('p-BoxPanel-child');
	    };
	    return BoxPanel;
	}(panel_1.Panel));
	exports.BoxPanel = BoxPanel;
	/**
	 * The namespace for the `BoxPanel` class statics.
	 */
	(function (BoxPanel) {
	    /**
	     * Get the box panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box panel stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return boxlayout_1.BoxLayout.getStretch(widget);
	    }
	    BoxPanel.getStretch = getStretch;
	    /**
	     * Set the box panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        boxlayout_1.BoxLayout.setStretch(widget, value);
	    }
	    BoxPanel.setStretch = setStretch;
	    /**
	     * Get the box panel size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box panel size basis for the widget.
	     */
	    function getSizeBasis(widget) {
	        return boxlayout_1.BoxLayout.getSizeBasis(widget);
	    }
	    BoxPanel.getSizeBasis = getSizeBasis;
	    /**
	     * Set the box panel size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the size basis.
	     */
	    function setSizeBasis(widget, value) {
	        boxlayout_1.BoxLayout.setSizeBasis(widget, value);
	    }
	    BoxPanel.setSizeBasis = setSizeBasis;
	})(BoxPanel = exports.BoxPanel || (exports.BoxPanel = {}));
	exports.BoxPanel = BoxPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a box layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new boxlayout_1.BoxLayout(options);
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var panellayout_1 = __webpack_require__(204);
	var widget_1 = __webpack_require__(202);
	/**
	 * A simple and convenient panel widget class.
	 *
	 * #### Notes
	 * This class is suitable as a base class for implementing a variety of
	 * convenience panel widgets, but can also be used directly with CSS to
	 * arrange a collection of widgets.
	 *
	 * This class provides a convenience wrapper around a [[PanelLayout]].
	 */
	var Panel = (function (_super) {
	    __extends(Panel, _super);
	    /**
	     * Construct a new panel.
	     *
	     * @param options - The options for initializing the panel.
	     */
	    function Panel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this.addClass('p-Panel');
	        _this.layout = Private.createLayout(options);
	        return _this;
	    }
	    Object.defineProperty(Panel.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the panel.
	         */
	        get: function () {
	            return this.layout.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a widget to the end of the panel.
	     *
	     * @param widget - The widget to add to the panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     */
	    Panel.prototype.addWidget = function (widget) {
	        this.layout.addWidget(widget);
	    };
	    /**
	     * Insert a widget at the specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     */
	    Panel.prototype.insertWidget = function (index, widget) {
	        this.layout.insertWidget(index, widget);
	    };
	    return Panel;
	}(widget_1.Widget));
	exports.Panel = Panel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a panel layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new panellayout_1.PanelLayout();
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var coreutils_1 = __webpack_require__(6);
	var commands_1 = __webpack_require__(208);
	var domutils_1 = __webpack_require__(192);
	var virtualdom_1 = __webpack_require__(211);
	var widget_1 = __webpack_require__(202);
	/**
	 * A widget which displays command items as a searchable palette.
	 */
	var CommandPalette = (function (_super) {
	    __extends(CommandPalette, _super);
	    /**
	     * Construct a new command palette.
	     *
	     * @param options - The options for initializing the palette.
	     */
	    function CommandPalette(options) {
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._activeIndex = -1;
	        _this._items = [];
	        _this._results = null;
	        _this.addClass('p-CommandPalette');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.commands = options.commands;
	        _this.renderer = options.renderer || CommandPalette.defaultRenderer;
	        _this.commands.commandChanged.connect(_this._onGenericChange, _this);
	        _this.commands.keyBindingChanged.connect(_this._onGenericChange, _this);
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    CommandPalette.prototype.dispose = function () {
	        this._items.length = 0;
	        this._results = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(CommandPalette.prototype, "searchNode", {
	        /**
	         * The command palette search node.
	         *
	         * #### Notes
	         * This is the node which contains the search-related elements.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-CommandPalette-search')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "inputNode", {
	        /**
	         * The command palette input node.
	         *
	         * #### Notes
	         * This is the actual input node for the search area.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-CommandPalette-input')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "contentNode", {
	        /**
	         * The command palette content node.
	         *
	         * #### Notes
	         * This is the node which holds the command item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-CommandPalette-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "items", {
	        /**
	         * A read-only array of the command items in the palette.
	         */
	        get: function () {
	            return this._items;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a command item to the command palette.
	     *
	     * @param options - The options for creating the command item.
	     *
	     * @returns The command item added to the palette.
	     */
	    CommandPalette.prototype.addItem = function (options) {
	        // Create a new command item for the options.
	        var item = Private.createItem(this.commands, options);
	        // Add the item to the array.
	        this._items.push(item);
	        // Refresh the search results.
	        this.refresh();
	        // Return the item added to the palette.
	        return item;
	    };
	    /**
	     * Remove an item from the command palette.
	     *
	     * @param item - The item to remove from the palette.
	     *
	     * #### Notes
	     * This is a no-op if the item is not in the palette.
	     */
	    CommandPalette.prototype.removeItem = function (item) {
	        this.removeItemAt(this._items.indexOf(item));
	    };
	    /**
	     * Remove the item at a given index from the command palette.
	     *
	     * @param index - The index of the item to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    CommandPalette.prototype.removeItemAt = function (index) {
	        // Remove the item from the array.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Bail if the index is out of range.
	        if (!item) {
	            return;
	        }
	        // Refresh the search results.
	        this.refresh();
	    };
	    /**
	     * Remove all items from the command palette.
	     */
	    CommandPalette.prototype.clearItems = function () {
	        // Bail if there is nothing to remove.
	        if (this._items.length === 0) {
	            return;
	        }
	        // Clear the array of items.
	        this._items.length = 0;
	        // Refresh the search results.
	        this.refresh();
	    };
	    /**
	     * Clear the search results and schedule an update.
	     *
	     * #### Notes
	     * This should be called whenever the search results of the palette
	     * should be updated.
	     *
	     * This is typically called automatically by the palette as needed,
	     * but can be called manually if the input text is programatically
	     * changed.
	     *
	     * The rendered results are updated asynchronously.
	     */
	    CommandPalette.prototype.refresh = function () {
	        this._results = null;
	        this.update();
	    };
	    /**
	     * Handle the DOM events for the command palette.
	     *
	     * @param event - The DOM event sent to the command palette.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the command palette's DOM node.
	     * It should not be called directly by user code.
	     */
	    CommandPalette.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'input':
	                this.refresh();
	                break;
	            case 'focus':
	            case 'blur':
	                this._toggleFocused();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    CommandPalette.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('click', this);
	        this.node.addEventListener('keydown', this);
	        this.node.addEventListener('input', this);
	        this.node.addEventListener('focus', this, true);
	        this.node.addEventListener('blur', this, true);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    CommandPalette.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('click', this);
	        this.node.removeEventListener('keydown', this);
	        this.node.removeEventListener('input', this);
	        this.node.removeEventListener('focus', this, true);
	        this.node.removeEventListener('blur', this, true);
	    };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     */
	    CommandPalette.prototype.onActivateRequest = function (msg) {
	        if (this.isAttached) {
	            var input = this.inputNode;
	            input.focus();
	            input.select();
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    CommandPalette.prototype.onUpdateRequest = function (msg) {
	        // Fetch the current query text and content node.
	        var query = this.inputNode.value;
	        var contentNode = this.contentNode;
	        // Ensure the search results are generated.
	        var results = this._results;
	        if (!results) {
	            // Generate and store the new search results.
	            results = this._results = Private.search(this._items, query);
	            // Reset the active index.
	            this._activeIndex = (query ? algorithm_1.ArrayExt.findFirstIndex(results, Private.canActivate) : -1);
	        }
	        // If there is no query and no results, clear the content.
	        if (!query && results.length === 0) {
	            virtualdom_1.VirtualDOM.render(null, contentNode);
	            return;
	        }
	        // If the is a query but no results, render the empty message.
	        if (query && results.length === 0) {
	            var content_1 = this.renderer.renderEmptyMessage({ query: query });
	            virtualdom_1.VirtualDOM.render(content_1, contentNode);
	            return;
	        }
	        // Create the render content for the search results.
	        var renderer = this.renderer;
	        var activeIndex = this._activeIndex;
	        var content = new Array(results.length);
	        for (var i = 0, n = results.length; i < n; ++i) {
	            var result = results[i];
	            if (result.type === 'header') {
	                var indices = result.indices;
	                var category = result.category;
	                content[i] = renderer.renderHeader({ category: category, indices: indices });
	            }
	            else {
	                var item = result.item;
	                var indices = result.indices;
	                var active = i === activeIndex;
	                content[i] = renderer.renderItem({ item: item, indices: indices, active: active });
	            }
	        }
	        // Render the search result content.
	        virtualdom_1.VirtualDOM.render(content, contentNode);
	        // Adjust the scroll position as needed.
	        if (activeIndex < 0 || activeIndex >= results.length) {
	            contentNode.scrollTop = 0;
	        }
	        else {
	            var element = contentNode.children[activeIndex];
	            domutils_1.ElementExt.scrollIntoViewIfNeeded(contentNode, element);
	        }
	    };
	    /**
	     * Handle the `'click'` event for the command palette.
	     */
	    CommandPalette.prototype._evtClick = function (event) {
	        // Bail if the click is not the left button.
	        if (event.button !== 0) {
	            return;
	        }
	        // Find the index of the item which was clicked.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return node.contains(event.target);
	        });
	        // Bail if the click was not on an item.
	        if (index === -1) {
	            return;
	        }
	        // Kill the event when a content item is clicked.
	        event.preventDefault();
	        event.stopPropagation();
	        // Execute the item if possible.
	        this._execute(index);
	    };
	    /**
	     * Handle the `'keydown'` event for the command palette.
	     */
	    CommandPalette.prototype._evtKeyDown = function (event) {
	        if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
	            return;
	        }
	        switch (event.keyCode) {
	            case 13:
	                event.preventDefault();
	                event.stopPropagation();
	                this._execute(this._activeIndex);
	                break;
	            case 38:
	                event.preventDefault();
	                event.stopPropagation();
	                this._activatePreviousItem();
	                break;
	            case 40:
	                event.preventDefault();
	                event.stopPropagation();
	                this._activateNextItem();
	                break;
	        }
	    };
	    /**
	     * Activate the next enabled command item.
	     */
	    CommandPalette.prototype._activateNextItem = function () {
	        // Bail if there are no search results.
	        if (!this._results || this._results.length === 0) {
	            return;
	        }
	        // Find the next enabled item index.
	        var ai = this._activeIndex;
	        var n = this._results.length;
	        var start = ai < n - 1 ? ai + 1 : 0;
	        var stop = start === 0 ? n - 1 : start - 1;
	        this._activeIndex = algorithm_1.ArrayExt.findFirstIndex(this._results, Private.canActivate, start, stop);
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Activate the previous enabled command item.
	     */
	    CommandPalette.prototype._activatePreviousItem = function () {
	        // Bail if there are no search results.
	        if (!this._results || this._results.length === 0) {
	            return;
	        }
	        // Find the previous enabled item index.
	        var ai = this._activeIndex;
	        var n = this._results.length;
	        var start = ai <= 0 ? n - 1 : ai - 1;
	        var stop = start === n - 1 ? 0 : start + 1;
	        this._activeIndex = algorithm_1.ArrayExt.findLastIndex(this._results, Private.canActivate, start, stop);
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Execute the command item at the given index, if possible.
	     */
	    CommandPalette.prototype._execute = function (index) {
	        // Bail if there are no search results.
	        if (!this._results) {
	            return;
	        }
	        // Bail if the index is out of range.
	        var part = this._results[index];
	        if (!part) {
	            return;
	        }
	        // Update the search text if the item is a header.
	        if (part.type === 'header') {
	            var input = this.inputNode;
	            input.value = part.category.toLowerCase() + " ";
	            input.focus();
	            this.refresh();
	            return;
	        }
	        // Bail if item is not enabled.
	        if (!part.item.isEnabled) {
	            return;
	        }
	        // Execute the item.
	        this.commands.execute(part.item.command, part.item.args);
	        // Clear the query text.
	        this.inputNode.value = '';
	        // Refresh the search results.
	        this.refresh();
	    };
	    /**
	     * Toggle the focused modifier based on the input node focus state.
	     */
	    CommandPalette.prototype._toggleFocused = function () {
	        var focused = document.activeElement === this.inputNode;
	        this.toggleClass('p-mod-focused', focused);
	    };
	    /**
	     * A signal handler for generic command changes.
	     */
	    CommandPalette.prototype._onGenericChange = function () {
	        this.refresh();
	    };
	    return CommandPalette;
	}(widget_1.Widget));
	exports.CommandPalette = CommandPalette;
	/**
	 * The namespace for the `CommandPalette` class statics.
	 */
	(function (CommandPalette) {
	    /**
	     * The default implementation of `IRenderer`.
	     */
	    var Renderer = (function () {
	        function Renderer() {
	        }
	        /**
	         * Render the virtual element for a command palette header.
	         *
	         * @param data - The data to use for rendering the header.
	         *
	         * @returns A virtual element representing the header.
	         */
	        Renderer.prototype.renderHeader = function (data) {
	            var content = this.formatHeader(data);
	            return virtualdom_1.h.li({ className: 'p-CommandPalette-header' }, content);
	        };
	        /**
	         * Render the virtual element for a command palette item.
	         *
	         * @param data - The data to use for rendering the item.
	         *
	         * @returns A virtual element representing the item.
	         */
	        Renderer.prototype.renderItem = function (data) {
	            var className = this.createItemClass(data);
	            var dataset = this.createItemDataset(data);
	            return (virtualdom_1.h.li({ className: className, dataset: dataset }, this.renderItemShortcut(data), this.renderItemLabel(data), this.renderItemCaption(data)));
	        };
	        /**
	         * Render the empty results message for a command palette.
	         *
	         * @param data - The data to use for rendering the message.
	         *
	         * @returns A virtual element representing the message.
	         */
	        Renderer.prototype.renderEmptyMessage = function (data) {
	            var content = this.formatEmptyMessage(data);
	            return virtualdom_1.h.li({ className: 'p-CommandPalette-emptyMessage' }, content);
	        };
	        /**
	         * Render the shortcut for a command palette item.
	         *
	         * @param data - The data to use for rendering the shortcut.
	         *
	         * @returns A virtual element representing the shortcut.
	         */
	        Renderer.prototype.renderItemShortcut = function (data) {
	            var content = this.formatItemShortcut(data);
	            return virtualdom_1.h.div({ className: 'p-CommandPalette-itemShortcut' }, content);
	        };
	        /**
	         * Render the label for a command palette item.
	         *
	         * @param data - The data to use for rendering the label.
	         *
	         * @returns A virtual element representing the label.
	         */
	        Renderer.prototype.renderItemLabel = function (data) {
	            var content = this.formatItemLabel(data);
	            return virtualdom_1.h.div({ className: 'p-CommandPalette-itemLabel' }, content);
	        };
	        /**
	         * Render the caption for a command palette item.
	         *
	         * @param data - The data to use for rendering the caption.
	         *
	         * @returns A virtual element representing the caption.
	         */
	        Renderer.prototype.renderItemCaption = function (data) {
	            var content = this.formatItemCaption(data);
	            return virtualdom_1.h.div({ className: 'p-CommandPalette-itemCaption' }, content);
	        };
	        /**
	         * Create the class name for the command palette item.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the command palette item.
	         */
	        Renderer.prototype.createItemClass = function (data) {
	            // Set up the initial class name.
	            var name = 'p-CommandPalette-item';
	            // Add the boolean state classes.
	            if (!data.item.isEnabled) {
	                name += ' p-mod-disabled';
	            }
	            if (data.item.isToggled) {
	                name += ' p-mod-toggled';
	            }
	            if (data.active) {
	                name += ' p-mod-active';
	            }
	            // Add the extra class.
	            var extra = data.item.className;
	            if (extra) {
	                name += " " + extra;
	            }
	            // Return the complete class name.
	            return name;
	        };
	        /**
	         * Create the dataset for the command palette item.
	         *
	         * @param data - The data to use for creating the dataset.
	         *
	         * @returns The dataset for the command palette item.
	         */
	        Renderer.prototype.createItemDataset = function (data) {
	            return __assign({}, data.item.dataset, { command: data.item.command });
	        };
	        /**
	         * Create the render content for the header node.
	         *
	         * @param data - The data to use for the header content.
	         *
	         * @returns The content to add to the header node.
	         */
	        Renderer.prototype.formatHeader = function (data) {
	            if (!data.indices || data.indices.length === 0) {
	                return data.category;
	            }
	            return algorithm_1.StringExt.highlight(data.category, data.indices, virtualdom_1.h.mark);
	        };
	        /**
	         * Create the render content for the empty message node.
	         *
	         * @param data - The data to use for the empty message content.
	         *
	         * @returns The content to add to the empty message node.
	         */
	        Renderer.prototype.formatEmptyMessage = function (data) {
	            return "No commands found that match '" + data.query + "'";
	        };
	        /**
	         * Create the render content for the item shortcut node.
	         *
	         * @param data - The data to use for the shortcut content.
	         *
	         * @returns The content to add to the shortcut node.
	         */
	        Renderer.prototype.formatItemShortcut = function (data) {
	            var kb = data.item.keyBinding;
	            return kb ? kb.keys.map(Private.formatKeystroke).join(', ') : null;
	        };
	        /**
	         * Create the render content for the item label node.
	         *
	         * @param data - The data to use for the label content.
	         *
	         * @returns The content to add to the label node.
	         */
	        Renderer.prototype.formatItemLabel = function (data) {
	            if (!data.indices || data.indices.length === 0) {
	                return data.item.label;
	            }
	            return algorithm_1.StringExt.highlight(data.item.label, data.indices, virtualdom_1.h.mark);
	        };
	        /**
	         * Create the render content for the item caption node.
	         *
	         * @param data - The data to use for the caption content.
	         *
	         * @returns The content to add to the caption node.
	         */
	        Renderer.prototype.formatItemCaption = function (data) {
	            return data.item.caption;
	        };
	        return Renderer;
	    }());
	    CommandPalette.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    CommandPalette.defaultRenderer = new Renderer();
	})(CommandPalette = exports.CommandPalette || (exports.CommandPalette = {}));
	exports.CommandPalette = CommandPalette;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the DOM node for a command palette.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var search = document.createElement('div');
	        var wrapper = document.createElement('div');
	        var input = document.createElement('input');
	        var content = document.createElement('ul');
	        search.className = 'p-CommandPalette-search';
	        wrapper.className = 'p-CommandPalette-wrapper';
	        input.className = 'p-CommandPalette-input';
	        content.className = 'p-CommandPalette-content';
	        input.spellcheck = false;
	        wrapper.appendChild(input);
	        search.appendChild(wrapper);
	        node.appendChild(search);
	        node.appendChild(content);
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Create a new command item from a command registry and options.
	     */
	    function createItem(commands, options) {
	        return new CommandItem(commands, options);
	    }
	    Private.createItem = createItem;
	    /**
	     * Format a keystroke for display on the local system.
	     */
	    function formatKeystroke(keystroke) {
	        var mods = '';
	        var parts = commands_1.CommandRegistry.parseKeystroke(keystroke);
	        if (domutils_1.Platform.IS_MAC) {
	            if (parts.ctrl) {
	                mods += '\u2303 ';
	            }
	            if (parts.alt) {
	                mods += '\u2325 ';
	            }
	            if (parts.shift) {
	                mods += '\u21E7 ';
	            }
	            if (parts.cmd) {
	                mods += '\u2318 ';
	            }
	        }
	        else {
	            if (parts.ctrl) {
	                mods += 'Ctrl+';
	            }
	            if (parts.alt) {
	                mods += 'Alt+';
	            }
	            if (parts.shift) {
	                mods += 'Shift+';
	            }
	        }
	        return mods + parts.key;
	    }
	    Private.formatKeystroke = formatKeystroke;
	    /**
	     * Search an array of command items for fuzzy matches.
	     */
	    function search(items, query) {
	        // Fuzzy match the items for the query.
	        var scores = matchItems(items, query);
	        // Sort the items based on their score.
	        scores.sort(scoreCmp);
	        // Create the results for the search.
	        return createResults(scores);
	    }
	    Private.search = search;
	    /**
	     * Test whether a result item can be activated.
	     */
	    function canActivate(result) {
	        return result.type === 'item' && result.item.isEnabled;
	    }
	    Private.canActivate = canActivate;
	    /**
	     * Normalize a category for a command item.
	     */
	    function normalizeCategory(category) {
	        return category.trim().replace(/\s+/g, ' ');
	    }
	    /**
	     * Normalize the query text for a fuzzy search.
	     */
	    function normalizeQuery(text) {
	        return text.replace(/\s+/g, '').toLowerCase();
	    }
	    /**
	     * Perform a fuzzy match on an array of command items.
	     */
	    function matchItems(items, query) {
	        // Normalize the query text to lower case with no whitespace.
	        query = normalizeQuery(query);
	        // Create the array to hold the scores.
	        var scores = [];
	        // Iterate over the items and match against the query.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Ignore items which are not visible.
	            var item = items[i];
	            if (!item.isVisible) {
	                continue;
	            }
	            // If the query is empty, all items are matched by default.
	            if (!query) {
	                scores.push({
	                    matchType: 3 /* Default */,
	                    categoryIndices: null,
	                    labelIndices: null,
	                    score: 0, item: item
	                });
	                continue;
	            }
	            // Run the fuzzy search for the item and query.
	            var score = fuzzySearch(item, query);
	            // Ignore the item if it is not a match.
	            if (!score) {
	                continue;
	            }
	            // Penalize disabled items.
	            // TODO - push disabled items all the way down in sort cmp?
	            if (!item.isEnabled) {
	                score.score += 1000;
	            }
	            // Add the score to the results.
	            scores.push(score);
	        }
	        // Return the final array of scores.
	        return scores;
	    }
	    /**
	     * Perform a fuzzy search on a single command item.
	     */
	    function fuzzySearch(item, query) {
	        // Create the source text to be searched.
	        var category = item.category.toLowerCase();
	        var label = item.label.toLowerCase();
	        var source = category + " " + label;
	        // Set up the match score and indices array.
	        var score = Infinity;
	        var indices = null;
	        // The regex for search word boundaries
	        var rgx = /\b\w/g;
	        // Search the source by word boundary.
	        while (true) {
	            // Find the next word boundary in the source.
	            var rgxMatch = rgx.exec(source);
	            // Break if there is no more source context.
	            if (!rgxMatch) {
	                break;
	            }
	            // Run the string match on the relevant substring.
	            var match = algorithm_1.StringExt.matchSumOfDeltas(source, query, rgxMatch.index);
	            // Break if there is no match.
	            if (!match) {
	                break;
	            }
	            // Update the match if the score is better.
	            if (match && match.score <= score) {
	                score = match.score;
	                indices = match.indices;
	            }
	        }
	        // Bail if there was no match.
	        if (!indices || score === Infinity) {
	            return null;
	        }
	        // Compute the pivot index between category and label text.
	        var pivot = category.length + 1;
	        // Find the slice index to separate matched indices.
	        var j = algorithm_1.ArrayExt.lowerBound(indices, pivot, function (a, b) { return a - b; });
	        // Extract the matched category and label indices.
	        var categoryIndices = indices.slice(0, j);
	        var labelIndices = indices.slice(j);
	        // Adjust the label indices for the pivot offset.
	        for (var i = 0, n = labelIndices.length; i < n; ++i) {
	            labelIndices[i] -= pivot;
	        }
	        // Handle a pure label match.
	        if (categoryIndices.length === 0) {
	            return {
	                matchType: 0 /* Label */,
	                categoryIndices: null,
	                labelIndices: labelIndices,
	                score: score, item: item
	            };
	        }
	        // Handle a pure category match.
	        if (labelIndices.length === 0) {
	            return {
	                matchType: 1 /* Category */,
	                categoryIndices: categoryIndices,
	                labelIndices: null,
	                score: score, item: item
	            };
	        }
	        // Handle a split match.
	        return {
	            matchType: 2 /* Split */,
	            categoryIndices: categoryIndices,
	            labelIndices: labelIndices,
	            score: score, item: item
	        };
	    }
	    /**
	     * A sort comparison function for a match score.
	     */
	    function scoreCmp(a, b) {
	        // First compare based on the match type
	        var m1 = a.matchType - b.matchType;
	        if (m1 !== 0) {
	            return m1;
	        }
	        // Otherwise, compare based on the match score.
	        var d1 = a.score - b.score;
	        if (d1 !== 0) {
	            return d1;
	        }
	        // Find the match index based on the match type.
	        var i1 = 0;
	        var i2 = 0;
	        switch (a.matchType) {
	            case 0 /* Label */:
	                i1 = a.labelIndices[0];
	                i2 = b.labelIndices[0];
	                break;
	            case 1 /* Category */:
	            case 2 /* Split */:
	                i1 = a.categoryIndices[0];
	                i2 = b.categoryIndices[0];
	                break;
	        }
	        // Compare based on the match index.
	        if (i1 !== i2) {
	            return i1 - i2;
	        }
	        // Otherwise, compare by category.
	        var d2 = a.item.category.localeCompare(b.item.category);
	        if (d2 !== 0) {
	            return d2;
	        }
	        // Otherwise, compare by rank.
	        var r1 = a.item.rank;
	        var r2 = b.item.rank;
	        if (r1 !== r2) {
	            return r1 < r2 ? -1 : 1; // Infinity safe
	        }
	        // Finally, compare by label.
	        return a.item.label.localeCompare(b.item.label);
	    }
	    /**
	     * Create the results from an array of sorted scores.
	     */
	    function createResults(scores) {
	        // Set up an array to track which scores have been visited.
	        var visited = new Array(scores.length);
	        algorithm_1.ArrayExt.fill(visited, false);
	        // Set up the search results array.
	        var results = [];
	        // Iterate over each score in the array.
	        for (var i = 0, n = scores.length; i < n; ++i) {
	            // Ignore a score which has already been processed.
	            if (visited[i]) {
	                continue;
	            }
	            // Extract the current item and indices.
	            var _a = scores[i], item = _a.item, categoryIndices = _a.categoryIndices;
	            // Extract the category for the current item.
	            var category = item.category;
	            // Add the header result for the category.
	            results.push({ type: 'header', category: category, indices: categoryIndices });
	            // Find the rest of the scores with the same category.
	            for (var j = i; j < n; ++j) {
	                // Ignore a score which has already been processed.
	                if (visited[j]) {
	                    continue;
	                }
	                // Extract the data for the current score.
	                var _b = scores[j], item_1 = _b.item, labelIndices = _b.labelIndices;
	                // Ignore an item with a different category.
	                if (item_1.category !== category) {
	                    continue;
	                }
	                // Create the item result for the score.
	                results.push({ type: 'item', item: item_1, indices: labelIndices });
	                // Mark the score as processed.
	                visited[j] = true;
	            }
	        }
	        // Return the final results.
	        return results;
	    }
	    /**
	     * A concrete implementation of `CommandPalette.IItem`.
	     */
	    var CommandItem = (function () {
	        /**
	         * Construct a new command item.
	         */
	        function CommandItem(commands, options) {
	            this._commands = commands;
	            this.category = normalizeCategory(options.category);
	            this.command = options.command;
	            this.args = options.args || coreutils_1.JSONExt.emptyObject;
	            this.rank = options.rank !== undefined ? options.rank : Infinity;
	        }
	        Object.defineProperty(CommandItem.prototype, "label", {
	            /**
	             * The display label for the command item.
	             */
	            get: function () {
	                return this._commands.label(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "caption", {
	            /**
	             * The display caption for the command item.
	             */
	            get: function () {
	                return this._commands.caption(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "className", {
	            /**
	             * The extra class name for the command item.
	             */
	            get: function () {
	                return this._commands.className(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "dataset", {
	            /**
	             * The dataset for the command item.
	             */
	            get: function () {
	                return this._commands.dataset(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "isEnabled", {
	            /**
	             * Whether the command item is enabled.
	             */
	            get: function () {
	                return this._commands.isEnabled(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "isToggled", {
	            /**
	             * Whether the command item is toggled.
	             */
	            get: function () {
	                return this._commands.isToggled(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "isVisible", {
	            /**
	             * Whether the command item is visible.
	             */
	            get: function () {
	                return this._commands.isVisible(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "keyBinding", {
	            /**
	             * The key binding for the command item.
	             */
	            get: function () {
	                var _a = this, command = _a.command, args = _a.args;
	                return algorithm_1.ArrayExt.findLastValue(this._commands.keyBindings, function (kb) {
	                    return kb.command === command && coreutils_1.JSONExt.deepEqual(kb.args, args);
	                }) || null;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        return CommandItem;
	    }());
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var coreutils_1 = __webpack_require__(6);
	var disposable_1 = __webpack_require__(209);
	var domutils_1 = __webpack_require__(192);
	var keyboard_1 = __webpack_require__(210);
	var signaling_1 = __webpack_require__(201);
	/**
	 * An object which manages a collection of commands.
	 *
	 * #### Notes
	 * A command registry can be used to populate a variety of action-based
	 * widgets, such as command palettes, menus, and toolbars.
	 */
	var CommandRegistry = (function () {
	    /**
	     * Construct a new command registry.
	     */
	    function CommandRegistry() {
	        this._timerID = 0;
	        this._replaying = false;
	        this._keystrokes = [];
	        this._keydownEvents = [];
	        this._keyBindings = [];
	        this._exactKeyMatch = null;
	        this._commands = Object.create(null);
	        this._commandChanged = new signaling_1.Signal(this);
	        this._commandExecuted = new signaling_1.Signal(this);
	        this._keyBindingChanged = new signaling_1.Signal(this);
	    }
	    Object.defineProperty(CommandRegistry.prototype, "commandChanged", {
	        /**
	         * A signal emitted when a command has changed.
	         *
	         * #### Notes
	         * This signal is useful for visual representations of commands which
	         * need to refresh when the state of a relevant command has changed.
	         */
	        get: function () {
	            return this._commandChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandRegistry.prototype, "commandExecuted", {
	        /**
	         * A signal emitted when a command has executed.
	         *
	         * #### Notes
	         * Care should be taken when consuming this signal. It is intended to
	         * be used largely for debugging and logging purposes. It should not
	         * be (ab)used for general purpose spying on command execution.
	         */
	        get: function () {
	            return this._commandExecuted;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandRegistry.prototype, "keyBindingChanged", {
	        /**
	         * A signal emitted when a key binding is changed.
	         */
	        get: function () {
	            return this._keyBindingChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandRegistry.prototype, "keyBindings", {
	        /**
	         * A read-only array of the key bindings in the registry.
	         */
	        get: function () {
	            return this._keyBindings;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * List the ids of the registered commands.
	     *
	     * @returns A new array of the registered command ids.
	     */
	    CommandRegistry.prototype.listCommands = function () {
	        return Object.keys(this._commands);
	    };
	    /**
	     * Test whether a specific command is registered.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @returns `true` if the command is registered, `false` otherwise.
	     */
	    CommandRegistry.prototype.hasCommand = function (id) {
	        return id in this._commands;
	    };
	    /**
	     * Add a command to the registry.
	     *
	     * @param id - The unique id of the command.
	     *
	     * @param options - The options for the command.
	     *
	     * @returns A disposable which will remove the command.
	     *
	     * @throws An error if the given `id` is already registered.
	     */
	    CommandRegistry.prototype.addCommand = function (id, options) {
	        var _this = this;
	        // Throw an error if the id is already registered.
	        if (id in this._commands) {
	            throw new Error("Command '" + id + "' already registered.");
	        }
	        // Add the command to the registry.
	        this._commands[id] = Private.createCommand(options);
	        // Emit the `commandChanged` signal.
	        this._commandChanged.emit({ id: id, type: 'added' });
	        // Return a disposable which will remove the command.
	        return new disposable_1.DisposableDelegate(function () {
	            // Remove the command from the registry.
	            delete _this._commands[id];
	            // Emit the `commandChanged` signal.
	            _this._commandChanged.emit({ id: id, type: 'removed' });
	        });
	    };
	    /**
	     * Notify listeners that the state of a command has changed.
	     *
	     * @param id - The id of the command which has changed.
	     *
	     * @throws An error if the given `id` is not registered.
	     *
	     * #### Notes
	     * This method should be called by the command author whenever the
	     * application state changes such that the results of the command
	     * metadata functions may have changed.
	     *
	     * This will cause the `commandChanged` signal to be emitted.
	     */
	    CommandRegistry.prototype.notifyCommandChanged = function (id) {
	        if (!(id in this._commands)) {
	            throw new Error("Command '" + id + "' is not registered.");
	        }
	        this._commandChanged.emit({ id: id, type: 'changed' });
	    };
	    /**
	     * Get the display label for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The display label for the command, or an empty string
	     *   if the command is not registered.
	     */
	    CommandRegistry.prototype.label = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.label.call(undefined, args) : '';
	    };
	    /**
	     * Get the mnemonic index for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The mnemonic index for the command, or `-1` if the
	     *   command is not registered.
	     */
	    CommandRegistry.prototype.mnemonic = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.mnemonic.call(undefined, args) : -1;
	    };
	    /**
	     * @deprecated Use `iconClass()` instead.
	     */
	    CommandRegistry.prototype.icon = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        return this.iconClass(id, args);
	    };
	    /**
	     * Get the icon class for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The icon class for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.iconClass = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.iconClass.call(undefined, args) : '';
	    };
	    /**
	     * Get the icon label for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The icon label for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.iconLabel = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.iconLabel.call(undefined, args) : '';
	    };
	    /**
	     * Get the short form caption for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The caption for the command, or an empty string if the
	     *   command is not registered.
	     */
	    CommandRegistry.prototype.caption = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.caption.call(undefined, args) : '';
	    };
	    /**
	     * Get the usage help text for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The usage text for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.usage = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.usage.call(undefined, args) : '';
	    };
	    /**
	     * Get the extra class name for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The class name for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.className = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.className.call(undefined, args) : '';
	    };
	    /**
	     * Get the dataset for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The dataset for the command, or an empty dataset if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.dataset = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.dataset.call(undefined, args) : {};
	    };
	    /**
	     * Test whether a specific command is enabled.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A boolean indicating whether the command is enabled,
	     *   or `false` if the command is not registered.
	     */
	    CommandRegistry.prototype.isEnabled = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.isEnabled.call(undefined, args) : false;
	    };
	    /**
	     * Test whether a specific command is toggled.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A boolean indicating whether the command is toggled,
	     *   or `false` if the command is not registered.
	     */
	    CommandRegistry.prototype.isToggled = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.isToggled.call(undefined, args) : false;
	    };
	    /**
	     * Test whether a specific command is visible.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A boolean indicating whether the command is visible,
	     *   or `false` if the command is not registered.
	     */
	    CommandRegistry.prototype.isVisible = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.isVisible.call(undefined, args) : false;
	    };
	    /**
	     * Execute a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A promise which resolves with the result of the command.
	     *
	     * #### Notes
	     * The promise will reject if the command throws an exception,
	     * or if the command is not registered.
	     */
	    CommandRegistry.prototype.execute = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        // Reject if the command is not registered.
	        var cmd = this._commands[id];
	        if (!cmd) {
	            return Promise.reject(new Error("Command '" + id + "' not registered."));
	        }
	        // Execute the command and reject if an exception is thrown.
	        var value;
	        try {
	            value = cmd.execute.call(undefined, args);
	        }
	        catch (err) {
	            value = Promise.reject(err);
	        }
	        // Create the return promise which resolves the result.
	        var result = Promise.resolve(value);
	        // Emit the command executed signal.
	        this._commandExecuted.emit({ id: id, args: args, result: result });
	        // Return the result promise to the caller.
	        return result;
	    };
	    /**
	     * Add a key binding to the registry.
	     *
	     * @param options - The options for creating the key binding.
	     *
	     * @returns A disposable which removes the added key binding.
	     *
	     * #### Notes
	     * If multiple key bindings are registered for the same sequence, the
	     * binding with the highest selector specificity is executed first. A
	     * tie is broken by using the most recently added key binding.
	     *
	     * Ambiguous key bindings are resolved with a timeout. As an example,
	     * suppose two key bindings are registered: one with the key sequence
	     * `['Ctrl D']`, and another with `['Ctrl D', 'Ctrl W']`. If the user
	     * presses `Ctrl D`, the first binding cannot be immediately executed
	     * since the user may intend to complete the chord with `Ctrl W`. For
	     * such cases, a timer is used to allow the chord to be completed. If
	     * the chord is not completed before the timeout, the first binding
	     * is executed.
	     */
	    CommandRegistry.prototype.addKeyBinding = function (options) {
	        var _this = this;
	        // Create the binding for the given options.
	        var binding = Private.createKeyBinding(options);
	        // Add the key binding to the bindings array.
	        this._keyBindings.push(binding);
	        // Emit the `bindingChanged` signal.
	        this._keyBindingChanged.emit({ binding: binding, type: 'added' });
	        // Return a disposable which will remove the binding.
	        return new disposable_1.DisposableDelegate(function () {
	            // Remove the binding from the array.
	            algorithm_1.ArrayExt.removeFirstOf(_this._keyBindings, binding);
	            // Emit the `bindingChanged` signal.
	            _this._keyBindingChanged.emit({ binding: binding, type: 'removed' });
	        });
	    };
	    /**
	     * Process a `'keydown'` event and invoke a matching key binding.
	     *
	     * @param event - The event object for a `'keydown'` event.
	     *
	     * #### Notes
	     * This should be called in response to a `'keydown'` event in order
	     * to invoke the command for the best matching key binding.
	     *
	     * The registry **does not** install its own listener for `'keydown'`
	     * events. This allows the application full control over the nodes
	     * and phase for which the registry processes `'keydown'` events.
	     */
	    CommandRegistry.prototype.processKeydownEvent = function (event) {
	        // Bail immediately if playing back keystrokes.
	        if (this._replaying) {
	            return;
	        }
	        // Get the normalized keystroke for the event.
	        var keystroke = CommandRegistry.keystrokeForKeydownEvent(event);
	        // If the keystroke is not valid for the keyboard layout, replay
	        // any suppressed events and clear the pending state.
	        if (!keystroke) {
	            this._replayKeydownEvents();
	            this._clearPendingState();
	            return;
	        }
	        // Add the keystroke to the current key sequence.
	        this._keystrokes.push(keystroke);
	        // Find the exact and partial matches for the key sequence.
	        var _a = Private.matchKeyBinding(this._keyBindings, this._keystrokes, event), exact = _a.exact, partial = _a.partial;
	        // If there is no exact match and no partial match, replay
	        // any suppressed events and clear the pending state.
	        if (!exact && !partial) {
	            this._replayKeydownEvents();
	            this._clearPendingState();
	            return;
	        }
	        // Stop propagation of the event. If there is only a partial match,
	        // the event will be replayed if a final exact match never occurs.
	        event.preventDefault();
	        event.stopPropagation();
	        // If there is an exact match but no partial match, the exact match
	        // can be dispatched immediately. The pending state is cleared so
	        // the next key press starts from the default state.
	        if (exact && !partial) {
	            this._executeKeyBinding(exact);
	            this._clearPendingState();
	            return;
	        }
	        // If there is both an exact match and a partial match, the exact
	        // match is stored for future dispatch in case the timer expires
	        // before a more specific match is triggered.
	        if (exact) {
	            this._exactKeyMatch = exact;
	        }
	        // Store the event for possible playback in the future.
	        this._keydownEvents.push(event);
	        // (Re)start the timer to dispatch the most recent exact match
	        // in case the partial match fails to result in an exact match.
	        this._startTimer();
	    };
	    /**
	     * Start or restart the pending timeout.
	     */
	    CommandRegistry.prototype._startTimer = function () {
	        var _this = this;
	        this._clearTimer();
	        this._timerID = setTimeout(function () {
	            _this._onPendingTimeout();
	        }, Private.CHORD_TIMEOUT);
	    };
	    /**
	     * Clear the pending timeout.
	     */
	    CommandRegistry.prototype._clearTimer = function () {
	        if (this._timerID !== 0) {
	            clearTimeout(this._timerID);
	            this._timerID = 0;
	        }
	    };
	    /**
	     * Replay the keydown events which were suppressed.
	     */
	    CommandRegistry.prototype._replayKeydownEvents = function () {
	        if (this._keydownEvents.length === 0) {
	            return;
	        }
	        this._replaying = true;
	        this._keydownEvents.forEach(Private.replayKeyEvent);
	        this._replaying = false;
	    };
	    /**
	     * Execute the command for the given key binding.
	     *
	     * If the command is missing or disabled, a warning will be logged.
	     */
	    CommandRegistry.prototype._executeKeyBinding = function (binding) {
	        var command = binding.command, args = binding.args;
	        if (!this.hasCommand(command) || !this.isEnabled(command, args)) {
	            var word = this.hasCommand(command) ? 'enabled' : 'registered';
	            var keys = binding.keys.join(', ');
	            var msg1 = "Cannot execute key binding '" + keys + "':";
	            var msg2 = "command '" + command + "' is not " + word + ".";
	            console.warn(msg1 + " " + msg2);
	            return;
	        }
	        this.execute(command, args);
	    };
	    /**
	     * Clear the internal pending state.
	     */
	    CommandRegistry.prototype._clearPendingState = function () {
	        this._clearTimer();
	        this._exactKeyMatch = null;
	        this._keystrokes.length = 0;
	        this._keydownEvents.length = 0;
	    };
	    /**
	     * Handle the partial match timeout.
	     */
	    CommandRegistry.prototype._onPendingTimeout = function () {
	        this._timerID = 0;
	        if (this._exactKeyMatch) {
	            this._executeKeyBinding(this._exactKeyMatch);
	        }
	        else {
	            this._replayKeydownEvents();
	        }
	        this._clearPendingState();
	    };
	    return CommandRegistry;
	}());
	exports.CommandRegistry = CommandRegistry;
	/**
	 * The namespace for the `CommandRegistry` class statics.
	 */
	(function (CommandRegistry) {
	    /**
	     * Parse a keystroke into its constituent components.
	     *
	     * @param keystroke - The keystroke of interest.
	     *
	     * @returns The parsed components of the keystroke.
	     *
	     * #### Notes
	     * The keystroke should be of the form:
	     *   `[<modifier 1> [<modifier 2> [<modifier N> ]]]<primary key>`
	     *
	     * The supported modifiers are: `Accel`, `Alt`, `Cmd`, `Ctrl`, and
	     * `Shift`. The `Accel` modifier is translated to `Cmd` on Mac and
	     * `Ctrl` on all other platforms.
	     *
	     * The parsing is tolerant and will not throw exceptions. Notably:
	     *   - Duplicate modifiers are ignored.
	     *   - Extra primary keys are ignored.
	     *   - The order of modifiers and primary key is irrelevant.
	     *   - The keystroke parts should be separated by whitespace.
	     *   - The keystroke is case sensitive.
	     */
	    function parseKeystroke(keystroke) {
	        var key = '';
	        var alt = false;
	        var cmd = false;
	        var ctrl = false;
	        var shift = false;
	        for (var _i = 0, _a = keystroke.split(/\s+/); _i < _a.length; _i++) {
	            var token = _a[_i];
	            if (token === 'Accel') {
	                if (domutils_1.Platform.IS_MAC) {
	                    cmd = true;
	                }
	                else {
	                    ctrl = true;
	                }
	            }
	            else if (token === 'Alt') {
	                alt = true;
	            }
	            else if (token === 'Cmd') {
	                cmd = true;
	            }
	            else if (token === 'Ctrl') {
	                ctrl = true;
	            }
	            else if (token === 'Shift') {
	                shift = true;
	            }
	            else if (token.length > 0) {
	                key = token;
	            }
	        }
	        return { cmd: cmd, ctrl: ctrl, alt: alt, shift: shift, key: key };
	    }
	    CommandRegistry.parseKeystroke = parseKeystroke;
	    /**
	     * Normalize a keystroke into a canonical representation.
	     *
	     * @param keystroke - The keystroke of interest.
	     *
	     * @returns The normalized representation of the keystroke.
	     *
	     * #### Notes
	     * This normalizes the keystroke by removing duplicate modifiers and
	     * extra primary keys, and assembling the parts in a canonical order.
	     *
	     * The `Cmd` modifier is ignored on non-Mac platforms.
	     */
	    function normalizeKeystroke(keystroke) {
	        var mods = '';
	        var parts = parseKeystroke(keystroke);
	        if (parts.ctrl) {
	            mods += 'Ctrl ';
	        }
	        if (parts.alt) {
	            mods += 'Alt ';
	        }
	        if (parts.shift) {
	            mods += 'Shift ';
	        }
	        if (parts.cmd && domutils_1.Platform.IS_MAC) {
	            mods += 'Cmd ';
	        }
	        return mods + parts.key;
	    }
	    CommandRegistry.normalizeKeystroke = normalizeKeystroke;
	    /**
	     * Create a normalized keystroke for a `'keydown'` event.
	     *
	     * @param event - The event object for a `'keydown'` event.
	     *
	     * @returns A normalized keystroke, or an empty string if the event
	     *   does not represent a valid keystroke for the given layout.
	     */
	    function keystrokeForKeydownEvent(event) {
	        var key = keyboard_1.getKeyboardLayout().keyForKeydownEvent(event);
	        if (!key) {
	            return '';
	        }
	        var mods = '';
	        if (event.ctrlKey) {
	            mods += 'Ctrl ';
	        }
	        if (event.altKey) {
	            mods += 'Alt ';
	        }
	        if (event.shiftKey) {
	            mods += 'Shift ';
	        }
	        if (event.metaKey && domutils_1.Platform.IS_MAC) {
	            mods += 'Cmd ';
	        }
	        return mods + key;
	    }
	    CommandRegistry.keystrokeForKeydownEvent = keystrokeForKeydownEvent;
	})(CommandRegistry = exports.CommandRegistry || (exports.CommandRegistry = {}));
	exports.CommandRegistry = CommandRegistry;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The timeout in ms for triggering a key binding chord.
	     */
	    Private.CHORD_TIMEOUT = 1000;
	    /**
	     * Create a normalized command from an options object.
	     */
	    function createCommand(options) {
	        return {
	            execute: options.execute,
	            label: asFunc(options.label, emptyStringFunc),
	            mnemonic: asFunc(options.mnemonic, negativeOneFunc),
	            iconClass: asFunc(options.iconClass || options.icon, emptyStringFunc),
	            iconLabel: asFunc(options.iconLabel, emptyStringFunc),
	            caption: asFunc(options.caption, emptyStringFunc),
	            usage: asFunc(options.usage, emptyStringFunc),
	            className: asFunc(options.className, emptyStringFunc),
	            dataset: asFunc(options.dataset, emptyDatasetFunc),
	            isEnabled: options.isEnabled || trueFunc,
	            isToggled: options.isToggled || falseFunc,
	            isVisible: options.isVisible || trueFunc
	        };
	    }
	    Private.createCommand = createCommand;
	    /**
	     * Create a key binding object from key binding options.
	     */
	    function createKeyBinding(options) {
	        return {
	            keys: normalizeKeys(options),
	            selector: validateSelector(options),
	            command: options.command,
	            args: options.args || coreutils_1.JSONExt.emptyObject
	        };
	    }
	    Private.createKeyBinding = createKeyBinding;
	    /**
	     * Find the key bindings which match a key sequence.
	     *
	     * This returns a match result which contains the best exact matching
	     * binding, and a flag which indicates if there are partial matches.
	     */
	    function matchKeyBinding(bindings, keys, event) {
	        // The current best exact match.
	        var exact = null;
	        // Whether a partial match has been found.
	        var partial = false;
	        // The match distance for the exact match.
	        var distance = Infinity;
	        // The specificity for the exact match.
	        var specificity = 0;
	        // Iterate over the bindings and search for the best match.
	        for (var i = 0, n = bindings.length; i < n; ++i) {
	            // Lookup the current binding.
	            var binding = bindings[i];
	            // Check whether the key binding sequence is a match.
	            var sqm = matchSequence(binding.keys, keys);
	            // If there is no match, the binding is ignored.
	            if (sqm === 0 /* None */) {
	                continue;
	            }
	            // If it is a partial match and no other partial match has been
	            // found, ensure the selector matches and set the partial flag.
	            if (sqm === 2 /* Partial */) {
	                if (!partial && targetDistance(binding.selector, event) !== -1) {
	                    partial = true;
	                }
	                continue;
	            }
	            // Ignore the match if the selector doesn't match, or if the
	            // matched node is farther away than the current best match.
	            var td = targetDistance(binding.selector, event);
	            if (td === -1 || td > distance) {
	                continue;
	            }
	            // Get the specificity for the selector.
	            var sp = domutils_1.Selector.calculateSpecificity(binding.selector);
	            // Update the best match if this match is stronger.
	            if (!exact || td < distance || sp >= specificity) {
	                exact = binding;
	                distance = td;
	                specificity = sp;
	            }
	        }
	        // Return the match result.
	        return { exact: exact, partial: partial };
	    }
	    Private.matchKeyBinding = matchKeyBinding;
	    /**
	     * Replay a keyboard event.
	     *
	     * This synthetically dispatches a clone of the keyboard event.
	     */
	    function replayKeyEvent(event) {
	        event.target.dispatchEvent(cloneKeyboardEvent(event));
	    }
	    Private.replayKeyEvent = replayKeyEvent;
	    /**
	     * A singleton empty string function.
	     */
	    var emptyStringFunc = function () { return ''; };
	    /**
	     * A singleton `-1` number function
	     */
	    var negativeOneFunc = function () { return -1; };
	    /**
	     * A singleton true boolean function.
	     */
	    var trueFunc = function () { return true; };
	    /**
	     * A singleton false boolean function.
	     */
	    var falseFunc = function () { return false; };
	    /**
	     * A singleton empty dataset function.
	     */
	    var emptyDatasetFunc = function () { return ({}); };
	    /**
	     * Cast a value or command func to a command func.
	     */
	    function asFunc(value, dfault) {
	        if (value === undefined) {
	            return dfault;
	        }
	        if (typeof value === 'function') {
	            return value;
	        }
	        return function () { return value; };
	    }
	    /**
	     * Get the platform-specific normalized keys for an options object.
	     */
	    function normalizeKeys(options) {
	        var keys;
	        if (domutils_1.Platform.IS_WIN) {
	            keys = options.winKeys || options.keys;
	        }
	        else if (domutils_1.Platform.IS_MAC) {
	            keys = options.macKeys || options.keys;
	        }
	        else {
	            keys = options.linuxKeys || options.keys;
	        }
	        return keys.map(CommandRegistry.normalizeKeystroke);
	    }
	    /**
	     * Validate the selector for an options object.
	     *
	     * This returns the validated selector, or throws if the selector is
	     * invalid or contains commas.
	     */
	    function validateSelector(options) {
	        if (options.selector.indexOf(',') !== -1) {
	            throw new Error("Selector cannot contain commas: " + options.selector);
	        }
	        if (!domutils_1.Selector.isValid(options.selector)) {
	            throw new Error("Invalid selector: " + options.selector);
	        }
	        return options.selector;
	    }
	    ;
	    /**
	     * Test whether a key binding sequence matches a key sequence.
	     *
	     * Returns a `SequenceMatch` value indicating the type of match.
	     */
	    function matchSequence(bindKeys, userKeys) {
	        if (bindKeys.length < userKeys.length) {
	            return 0 /* None */;
	        }
	        for (var i = 0, n = userKeys.length; i < n; ++i) {
	            if (bindKeys[i] !== userKeys[i]) {
	                return 0 /* None */;
	            }
	        }
	        if (bindKeys.length > userKeys.length) {
	            return 2 /* Partial */;
	        }
	        return 1 /* Exact */;
	    }
	    /**
	     * Find the distance from the target node to the first matching node.
	     *
	     * This traverses the event path from `target` to `currentTarget` and
	     * computes the distance from `target` to the first node which matches
	     * the CSS selector. If no match is found, `-1` is returned.
	     */
	    function targetDistance(selector, event) {
	        var targ = event.target;
	        var curr = event.currentTarget;
	        for (var dist = 0; targ !== null; targ = targ.parentElement, ++dist) {
	            if (domutils_1.Selector.matches(targ, selector)) {
	                return dist;
	            }
	            if (targ === curr) {
	                return -1;
	            }
	        }
	        return -1;
	    }
	    /**
	     * Clone a keyboard event.
	     */
	    function cloneKeyboardEvent(event) {
	        // A custom event is required because Chrome nulls out the
	        // `keyCode` field in user-generated `KeyboardEvent` types.
	        var clone = document.createEvent('Event');
	        var bubbles = event.bubbles || true;
	        var cancelable = event.cancelable || true;
	        clone.initEvent(event.type || 'keydown', bubbles, cancelable);
	        clone.key = event.key || '';
	        clone.keyCode = event.keyCode || 0;
	        clone.which = event.keyCode || 0;
	        clone.ctrlKey = event.ctrlKey || false;
	        clone.altKey = event.altKey || false;
	        clone.shiftKey = event.shiftKey || false;
	        clone.metaKey = event.metaKey || false;
	        clone.view = event.view || window;
	        return clone;
	    }
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	/**
	 * A disposable object which delegates to a callback function.
	 */
	var DisposableDelegate = (function () {
	    /**
	     * Construct a new disposable delegate.
	     *
	     * @param fn - The callback function to invoke on dispose.
	     */
	    function DisposableDelegate(fn) {
	        this._fn = fn;
	    }
	    Object.defineProperty(DisposableDelegate.prototype, "isDisposed", {
	        /**
	         * Test whether the delegate has been disposed.
	         */
	        get: function () {
	            return !this._fn;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the delegate and invoke the callback function.
	     */
	    DisposableDelegate.prototype.dispose = function () {
	        if (!this._fn) {
	            return;
	        }
	        var fn = this._fn;
	        this._fn = null;
	        fn();
	    };
	    return DisposableDelegate;
	}());
	exports.DisposableDelegate = DisposableDelegate;
	/**
	 * An object which manages a collection of disposable items.
	 */
	var DisposableSet = (function () {
	    /**
	     * Construct a new disposable set.
	     */
	    function DisposableSet() {
	        this._disposed = false;
	        this._items = new Set();
	    }
	    Object.defineProperty(DisposableSet.prototype, "isDisposed", {
	        /**
	         * Test whether the set has been disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the set and the items it contains.
	     *
	     * #### Notes
	     * Items are disposed in the order they are added to the set.
	     */
	    DisposableSet.prototype.dispose = function () {
	        if (this._disposed) {
	            return;
	        }
	        this._disposed = true;
	        this._items.forEach(function (item) { item.dispose(); });
	        this._items.clear();
	    };
	    /**
	     * Test whether the set contains a specific item.
	     *
	     * @param item - The item of interest.
	     *
	     * @returns `true` if the set contains the item, `false` otherwise.
	     */
	    DisposableSet.prototype.contains = function (item) {
	        return this._items.has(item);
	    };
	    /**
	     * Add a disposable item to the set.
	     *
	     * @param item - The item to add to the set.
	     *
	     * #### Notes
	     * If the item is already contained in the set, this is a no-op.
	     */
	    DisposableSet.prototype.add = function (item) {
	        this._items.add(item);
	    };
	    /**
	     * Remove a disposable item from the set.
	     *
	     * @param item - The item to remove from the set.
	     *
	     * #### Notes
	     * If the item is not contained in the set, this is a no-op.
	     */
	    DisposableSet.prototype.remove = function (item) {
	        this._items.delete(item);
	    };
	    /**
	     * Remove all items from the set.
	     */
	    DisposableSet.prototype.clear = function () {
	        this._items.clear();
	    };
	    return DisposableSet;
	}());
	exports.DisposableSet = DisposableSet;
	/**
	 * The namespace for the `DisposableSet` class statics.
	 */
	(function (DisposableSet) {
	    /**
	     * Create a disposable set from an iterable of items.
	     *
	     * @param items - The iterable or array-like object of interest.
	     *
	     * @returns A new disposable initialized with the given items.
	     */
	    function from(items) {
	        var set = new DisposableSet();
	        algorithm_1.each(items, function (item) { set.add(item); });
	        return set;
	    }
	    DisposableSet.from = from;
	})(DisposableSet = exports.DisposableSet || (exports.DisposableSet = {}));
	exports.DisposableSet = DisposableSet;


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

	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Get the global application keyboard layout instance.
	 *
	 * @returns The keyboard layout for use by the application.
	 *
	 * #### Notes
	 * The default keyboard layout is US-English.
	 */
	function getKeyboardLayout() {
	    return Private.keyboardLayout;
	}
	exports.getKeyboardLayout = getKeyboardLayout;
	/**
	 * Set the global application keyboard layout instance.
	 *
	 * @param - The keyboard layout for use by the application.
	 *
	 * #### Notes
	 * The keyboard layout should typically be set on application startup
	 * to a layout which is appropriate for the user's system.
	 */
	function setKeyboardLayout(layout) {
	    Private.keyboardLayout = layout;
	}
	exports.setKeyboardLayout = setKeyboardLayout;
	/**
	 * A concrete implementation of [[IKeyboardLayout]] based on keycodes.
	 *
	 * The `keyCode` property of a `'keydown'` event is a browser and OS
	 * specific representation of the physical key (not character) which
	 * was pressed on a keyboard. While not the most convenient API, it
	 * is currently the only one which works reliably on all browsers.
	 *
	 * This class accepts a user-defined mapping of keycode to key, which
	 * allows for reliable shortcuts tailored to the user's system.
	 */
	var KeycodeLayout = (function () {
	    /**
	     * Construct a new keycode layout.
	     *
	     * @param name - The human readable name for the layout.
	     *
	     * @param codes - A mapping of keycode to key value.
	     */
	    function KeycodeLayout(name, codes) {
	        this.name = name;
	        this._codes = codes;
	        this._keys = KeycodeLayout.extractKeys(codes);
	    }
	    /**
	     * Get an array of the key values supported by the layout.
	     *
	     * @returns A new array of the supported key values.
	     */
	    KeycodeLayout.prototype.keys = function () {
	        return Object.keys(this._keys);
	    };
	    /**
	     * Test whether the given key is a valid value for the layout.
	     *
	     * @param key - The user provided key to test for validity.
	     *
	     * @returns `true` if the key is valid, `false` otherwise.
	     */
	    KeycodeLayout.prototype.isValidKey = function (key) {
	        return key in this._keys;
	    };
	    /**
	     * Get the key for a `'keydown'` event.
	     *
	     * @param event - The event object for a `'keydown'` event.
	     *
	     * @returns The associated key value, or an empty string if
	     *   the event does not represent a valid primary key.
	     */
	    KeycodeLayout.prototype.keyForKeydownEvent = function (event) {
	        return this._codes[event.keyCode] || '';
	    };
	    return KeycodeLayout;
	}());
	exports.KeycodeLayout = KeycodeLayout;
	/**
	 * The namespace for the `KeycodeLayout` class statics.
	 */
	(function (KeycodeLayout) {
	    /**
	     * Extract the set of keys from a code map.
	     *
	     * @param code - The code map of interest.
	     *
	     * @returns A set of the keys in the code map.
	     */
	    function extractKeys(codes) {
	        var keys = Object.create(null);
	        for (var c in codes) {
	            keys[codes[c]] = true;
	        }
	        return keys;
	    }
	    KeycodeLayout.extractKeys = extractKeys;
	})(KeycodeLayout = exports.KeycodeLayout || (exports.KeycodeLayout = {}));
	exports.KeycodeLayout = KeycodeLayout;
	/**
	 * A keycode-based keyboard layout for US English keyboards.
	 *
	 * This layout is valid for the following OS/Browser combinations.
	 *
	 * - Windows
	 *   - Chrome
	 *   - Firefox
	 *   - IE
	 *
	 * - OSX
	 *   - Chrome
	 *   - Firefox
	 *   - Safari
	 *
	 * - Linux
	 *   - Chrome
	 *   - Firefox
	 *
	 * Other combinations may also work, but are untested.
	 */
	exports.EN_US = new KeycodeLayout('en-us', {
	    8: 'Backspace',
	    9: 'Tab',
	    13: 'Enter',
	    19: 'Pause',
	    27: 'Escape',
	    32: 'Space',
	    33: 'PageUp',
	    34: 'PageDown',
	    35: 'End',
	    36: 'Home',
	    37: 'ArrowLeft',
	    38: 'ArrowUp',
	    39: 'ArrowRight',
	    40: 'ArrowDown',
	    45: 'Insert',
	    46: 'Delete',
	    48: '0',
	    49: '1',
	    50: '2',
	    51: '3',
	    52: '4',
	    53: '5',
	    54: '6',
	    55: '7',
	    56: '8',
	    57: '9',
	    59: ';',
	    61: '=',
	    65: 'A',
	    66: 'B',
	    67: 'C',
	    68: 'D',
	    69: 'E',
	    70: 'F',
	    71: 'G',
	    72: 'H',
	    73: 'I',
	    74: 'J',
	    75: 'K',
	    76: 'L',
	    77: 'M',
	    78: 'N',
	    79: 'O',
	    80: 'P',
	    81: 'Q',
	    82: 'R',
	    83: 'S',
	    84: 'T',
	    85: 'U',
	    86: 'V',
	    87: 'W',
	    88: 'X',
	    89: 'Y',
	    90: 'Z',
	    93: 'ContextMenu',
	    96: '0',
	    97: '1',
	    98: '2',
	    99: '3',
	    100: '4',
	    101: '5',
	    102: '6',
	    103: '7',
	    104: '8',
	    105: '9',
	    106: '*',
	    107: '+',
	    109: '-',
	    110: '.',
	    111: '/',
	    112: 'F1',
	    113: 'F2',
	    114: 'F3',
	    115: 'F4',
	    116: 'F5',
	    117: 'F6',
	    118: 'F7',
	    119: 'F8',
	    120: 'F9',
	    121: 'F10',
	    122: 'F11',
	    123: 'F12',
	    173: '-',
	    186: ';',
	    187: '=',
	    188: ',',
	    189: '-',
	    190: '.',
	    191: '/',
	    192: '`',
	    219: '[',
	    220: '\\',
	    221: ']',
	    222: '\''
	});
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The global keyboard layout instance.
	     */
	    Private.keyboardLayout = exports.EN_US;
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	/**
	 * A virtual node which represents plain text content.
	 *
	 * #### Notes
	 * User code will not typically create a `VirtualText` node directly.
	 * Instead, the `h()` function will be used to create an element tree.
	 */
	var VirtualText = (function () {
	    /**
	     * Construct a new virtual text node.
	     *
	     * @param content - The text content for the node.
	     */
	    function VirtualText(content) {
	        /**
	         * The type of the node.
	         *
	         * This value can be used as a type guard for discriminating the
	         * `VirtualNode` union type.
	         */
	        this.type = 'text';
	        this.content = content;
	    }
	    return VirtualText;
	}());
	exports.VirtualText = VirtualText;
	/**
	 * A virtual node which represents an HTML element.
	 *
	 * #### Notes
	 * User code will not typically create a `VirtualElement` node directly.
	 * Instead, the `h()` function will be used to create an element tree.
	 */
	var VirtualElement = (function () {
	    /**
	     * Construct a new virtual element node.
	     *
	     * @param tag - The element tag name.
	     *
	     * @param attrs - The element attributes.
	     *
	     * @param children - The element children.
	     */
	    function VirtualElement(tag, attrs, children) {
	        /**
	         * The type of the node.
	         *
	         * This value can be used as a type guard for discriminating the
	         * `VirtualNode` union type.
	         */
	        this.type = 'element';
	        this.tag = tag;
	        this.attrs = attrs;
	        this.children = children;
	    }
	    return VirtualElement;
	}());
	exports.VirtualElement = VirtualElement;
	function h(tag) {
	    var attrs = {};
	    var children = [];
	    for (var i = 1, n = arguments.length; i < n; ++i) {
	        var arg = arguments[i];
	        if (typeof arg === 'string') {
	            children.push(new VirtualText(arg));
	        }
	        else if (arg instanceof VirtualText) {
	            children.push(arg);
	        }
	        else if (arg instanceof VirtualElement) {
	            children.push(arg);
	        }
	        else if (arg instanceof Array) {
	            extend(children, arg);
	        }
	        else if (i === 1 && arg && typeof arg === 'object') {
	            attrs = arg;
	        }
	    }
	    return new VirtualElement(tag, attrs, children);
	    function extend(array, values) {
	        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
	            var child = values_1[_i];
	            if (typeof child === 'string') {
	                array.push(new VirtualText(child));
	            }
	            else if (child instanceof VirtualText) {
	                array.push(child);
	            }
	            else if (child instanceof VirtualElement) {
	                array.push(child);
	            }
	        }
	    }
	}
	exports.h = h;
	/**
	 * The namespace for the `h` function statics.
	 */
	(function (h) {
	    h.a = h.bind(undefined, 'a');
	    h.abbr = h.bind(undefined, 'abbr');
	    h.address = h.bind(undefined, 'address');
	    h.area = h.bind(undefined, 'area');
	    h.article = h.bind(undefined, 'article');
	    h.aside = h.bind(undefined, 'aside');
	    h.audio = h.bind(undefined, 'audio');
	    h.b = h.bind(undefined, 'b');
	    h.bdi = h.bind(undefined, 'bdi');
	    h.bdo = h.bind(undefined, 'bdo');
	    h.blockquote = h.bind(undefined, 'blockquote');
	    h.br = h.bind(undefined, 'br');
	    h.button = h.bind(undefined, 'button');
	    h.canvas = h.bind(undefined, 'canvas');
	    h.caption = h.bind(undefined, 'caption');
	    h.cite = h.bind(undefined, 'cite');
	    h.code = h.bind(undefined, 'code');
	    h.col = h.bind(undefined, 'col');
	    h.colgroup = h.bind(undefined, 'colgroup');
	    h.data = h.bind(undefined, 'data');
	    h.datalist = h.bind(undefined, 'datalist');
	    h.dd = h.bind(undefined, 'dd');
	    h.del = h.bind(undefined, 'del');
	    h.dfn = h.bind(undefined, 'dfn');
	    h.div = h.bind(undefined, 'div');
	    h.dl = h.bind(undefined, 'dl');
	    h.dt = h.bind(undefined, 'dt');
	    h.em = h.bind(undefined, 'em');
	    h.embed = h.bind(undefined, 'embed');
	    h.fieldset = h.bind(undefined, 'fieldset');
	    h.figcaption = h.bind(undefined, 'figcaption');
	    h.figure = h.bind(undefined, 'figure');
	    h.footer = h.bind(undefined, 'footer');
	    h.form = h.bind(undefined, 'form');
	    h.h1 = h.bind(undefined, 'h1');
	    h.h2 = h.bind(undefined, 'h2');
	    h.h3 = h.bind(undefined, 'h3');
	    h.h4 = h.bind(undefined, 'h4');
	    h.h5 = h.bind(undefined, 'h5');
	    h.h6 = h.bind(undefined, 'h6');
	    h.header = h.bind(undefined, 'header');
	    h.hr = h.bind(undefined, 'hr');
	    h.i = h.bind(undefined, 'i');
	    h.iframe = h.bind(undefined, 'iframe');
	    h.img = h.bind(undefined, 'img');
	    h.input = h.bind(undefined, 'input');
	    h.ins = h.bind(undefined, 'ins');
	    h.kbd = h.bind(undefined, 'kbd');
	    h.label = h.bind(undefined, 'label');
	    h.legend = h.bind(undefined, 'legend');
	    h.li = h.bind(undefined, 'li');
	    h.main = h.bind(undefined, 'main');
	    h.map = h.bind(undefined, 'map');
	    h.mark = h.bind(undefined, 'mark');
	    h.meter = h.bind(undefined, 'meter');
	    h.nav = h.bind(undefined, 'nav');
	    h.noscript = h.bind(undefined, 'noscript');
	    h.object = h.bind(undefined, 'object');
	    h.ol = h.bind(undefined, 'ol');
	    h.optgroup = h.bind(undefined, 'optgroup');
	    h.option = h.bind(undefined, 'option');
	    h.output = h.bind(undefined, 'output');
	    h.p = h.bind(undefined, 'p');
	    h.param = h.bind(undefined, 'param');
	    h.pre = h.bind(undefined, 'pre');
	    h.progress = h.bind(undefined, 'progress');
	    h.q = h.bind(undefined, 'q');
	    h.rp = h.bind(undefined, 'rp');
	    h.rt = h.bind(undefined, 'rt');
	    h.ruby = h.bind(undefined, 'ruby');
	    h.s = h.bind(undefined, 's');
	    h.samp = h.bind(undefined, 'samp');
	    h.section = h.bind(undefined, 'section');
	    h.select = h.bind(undefined, 'select');
	    h.small = h.bind(undefined, 'small');
	    h.source = h.bind(undefined, 'source');
	    h.span = h.bind(undefined, 'span');
	    h.strong = h.bind(undefined, 'strong');
	    h.sub = h.bind(undefined, 'sub');
	    h.summary = h.bind(undefined, 'summary');
	    h.sup = h.bind(undefined, 'sup');
	    h.table = h.bind(undefined, 'table');
	    h.tbody = h.bind(undefined, 'tbody');
	    h.td = h.bind(undefined, 'td');
	    h.textarea = h.bind(undefined, 'textarea');
	    h.tfoot = h.bind(undefined, 'tfoot');
	    h.th = h.bind(undefined, 'th');
	    h.thead = h.bind(undefined, 'thead');
	    h.time = h.bind(undefined, 'time');
	    h.title = h.bind(undefined, 'title');
	    h.tr = h.bind(undefined, 'tr');
	    h.track = h.bind(undefined, 'track');
	    h.u = h.bind(undefined, 'u');
	    h.ul = h.bind(undefined, 'ul');
	    h.var_ = h.bind(undefined, 'var');
	    h.video = h.bind(undefined, 'video');
	    h.wbr = h.bind(undefined, 'wbr');
	})(h = exports.h || (exports.h = {}));
	/**
	 * The namespace for the virtual DOM rendering functions.
	 */
	var VirtualDOM;
	(function (VirtualDOM) {
	    /**
	     * Create a real DOM element from a virtual element node.
	     *
	     * @param node - The virtual element node to realize.
	     *
	     * @returns A new DOM element for the given virtual element node.
	     *
	     * #### Notes
	     * This creates a brand new *real* DOM element with a structure which
	     * matches the given virtual DOM node.
	     *
	     * If virtual diffing is desired, use the `render` function instead.
	     */
	    function realize(node) {
	        return Private.createDOMNode(node);
	    }
	    VirtualDOM.realize = realize;
	    /**
	     * Render virtual DOM content into a host element.
	     *
	     * @param content - The virtual DOM content to render.
	     *
	     * @param host - The host element for the rendered content.
	     *
	     * #### Notes
	     * This renders the delta from the previous rendering. It assumes that
	     * the content of the host element is not manipulated by external code.
	     *
	     * Providing `null` content will clear the rendering.
	     *
	     * Externally modifying the provided content or the host element will
	     * result in undefined rendering behavior.
	     */
	    function render(content, host) {
	        var oldContent = Private.hostMap.get(host) || [];
	        var newContent = Private.asContentArray(content);
	        Private.hostMap.set(host, newContent);
	        Private.updateContent(host, oldContent, newContent);
	    }
	    VirtualDOM.render = render;
	})(VirtualDOM = exports.VirtualDOM || (exports.VirtualDOM = {}));
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A weak mapping of host element to virtual DOM content.
	     */
	    Private.hostMap = new WeakMap();
	    /**
	     * Cast a content value to a content array.
	     */
	    function asContentArray(value) {
	        if (!value) {
	            return [];
	        }
	        if (value instanceof Array) {
	            return value;
	        }
	        return [value];
	    }
	    Private.asContentArray = asContentArray;
	    function createDOMNode(node) {
	        // Create a text node for a virtual text node.
	        if (node.type === 'text') {
	            return document.createTextNode(node.content);
	        }
	        // Create the HTML element with the specified tag.
	        var element = document.createElement(node.tag);
	        // Add the attributes for the new element.
	        addAttrs(element, node.attrs);
	        // Recursively populate the element with child content.
	        for (var i = 0, n = node.children.length; i < n; ++i) {
	            element.appendChild(createDOMNode(node.children[i]));
	        }
	        // Return the populated element.
	        return element;
	    }
	    Private.createDOMNode = createDOMNode;
	    /**
	     * Update a host element with the delta of the virtual content.
	     *
	     * This is the core "diff" algorithm. There is no explicit "patch"
	     * phase. The host is patched at each step as the diff progresses.
	     */
	    function updateContent(host, oldContent, newContent) {
	        // Bail early if the content is identical.
	        if (oldContent === newContent) {
	            return;
	        }
	        // Collect the old keyed elems into a mapping.
	        var oldKeyed = collectKeys(host, oldContent);
	        // Create a copy of the old content which can be modified in-place.
	        var oldCopy = oldContent.slice();
	        // Update the host with the new content. The diff always proceeds
	        // forward and never modifies a previously visited index. The old
	        // copy array is modified in-place to reflect the changes made to
	        // the host children. This causes the stale nodes to be pushed to
	        // the end of the host node and removed at the end of the loop.
	        var currElem = host.firstChild;
	        var newCount = newContent.length;
	        for (var i = 0; i < newCount; ++i) {
	            // If the old content is exhausted, create a new node.
	            if (i >= oldCopy.length) {
	                host.appendChild(createDOMNode(newContent[i]));
	                continue;
	            }
	            // Lookup the old and new virtual nodes.
	            var oldVNode = oldCopy[i];
	            var newVNode = newContent[i];
	            // If both elements are identical, there is nothing to do.
	            if (oldVNode === newVNode) {
	                currElem = currElem.nextSibling;
	                continue;
	            }
	            // Handle the simplest case of in-place text update first.
	            if (oldVNode.type === 'text' && newVNode.type === 'text') {
	                currElem.textContent = newVNode.content;
	                currElem = currElem.nextSibling;
	                continue;
	            }
	            // If the old or new node is a text node, the other node is now
	            // known to be an element node, so create and insert a new node.
	            if (oldVNode.type === 'text' || newVNode.type === 'text') {
	                algorithm_1.ArrayExt.insert(oldCopy, i, newVNode);
	                host.insertBefore(createDOMNode(newVNode), currElem);
	                continue;
	            }
	            // At this point, both nodes are known to be element nodes.
	            // If the new elem is keyed, move an old keyed elem to the proper
	            // location before proceeding with the diff. The search can start
	            // at the current index, since the unmatched old keyed elems are
	            // pushed forward in the old copy array.
	            var newKey = newVNode.attrs.key;
	            if (newKey && newKey in oldKeyed) {
	                var pair = oldKeyed[newKey];
	                if (pair.vNode !== oldVNode) {
	                    algorithm_1.ArrayExt.move(oldCopy, oldCopy.indexOf(pair.vNode, i + 1), i);
	                    host.insertBefore(pair.element, currElem);
	                    oldVNode = pair.vNode;
	                    currElem = pair.element;
	                }
	            }
	            // If both elements are identical, there is nothing to do.
	            if (oldVNode === newVNode) {
	                currElem = currElem.nextSibling;
	                continue;
	            }
	            // If the old elem is keyed and does not match the new elem key,
	            // create a new node. This is necessary since the old keyed elem
	            // may be matched at a later point in the diff.
	            var oldKey = oldVNode.attrs.key;
	            if (oldKey && oldKey !== newKey) {
	                algorithm_1.ArrayExt.insert(oldCopy, i, newVNode);
	                host.insertBefore(createDOMNode(newVNode), currElem);
	                continue;
	            }
	            // If the tags are different, create a new node.
	            if (oldVNode.tag !== newVNode.tag) {
	                algorithm_1.ArrayExt.insert(oldCopy, i, newVNode);
	                host.insertBefore(createDOMNode(newVNode), currElem);
	                continue;
	            }
	            // At this point, the element can be updated in-place.
	            // Update the element attributes.
	            updateAttrs(currElem, oldVNode.attrs, newVNode.attrs);
	            // Update the element content.
	            updateContent(currElem, oldVNode.children, newVNode.children);
	            // Step to the next sibling element.
	            currElem = currElem.nextSibling;
	        }
	        // Dispose of the old nodes pushed to the end of the host.
	        for (var i = oldCopy.length - newCount; i > 0; --i) {
	            host.removeChild(host.lastChild);
	        }
	    }
	    Private.updateContent = updateContent;
	    /**
	     * A set of special-cased attribute names.
	     */
	    var specialAttrs = {
	        'key': true,
	        'className': true,
	        'htmlFor': true,
	        'dataset': true,
	        'style': true,
	    };
	    /**
	     * Add element attributes to a newly created HTML element.
	     */
	    function addAttrs(element, attrs) {
	        // Add the inline event listeners and node attributes.
	        for (var name_1 in attrs) {
	            if (name_1 in specialAttrs) {
	                continue;
	            }
	            if (name_1.substr(0, 2) === 'on') {
	                element[name_1] = attrs[name_1];
	            }
	            else {
	                element.setAttribute(name_1, attrs[name_1]);
	            }
	        }
	        // Add the element `class` attribute.
	        if (attrs.className !== undefined) {
	            element.setAttribute('class', attrs.className);
	        }
	        // Add the element `for` attribute.
	        if (attrs.htmlFor !== undefined) {
	            element.setAttribute('for', attrs.htmlFor);
	        }
	        // Add the dataset values.
	        if (attrs.dataset) {
	            addDataset(element, attrs.dataset);
	        }
	        // Add the inline styles.
	        if (attrs.style) {
	            addStyle(element, attrs.style);
	        }
	    }
	    /**
	     * Update the element attributes of an HTML element.
	     */
	    function updateAttrs(element, oldAttrs, newAttrs) {
	        // Do nothing if the attrs are the same object.
	        if (oldAttrs === newAttrs) {
	            return;
	        }
	        // Setup the strongly typed loop variable.
	        var name;
	        // Remove attributes and listeners which no longer exist.
	        for (name in oldAttrs) {
	            if (name in specialAttrs || name in newAttrs) {
	                continue;
	            }
	            if (name.substr(0, 2) === 'on') {
	                element[name] = null;
	            }
	            else {
	                element.removeAttribute(name);
	            }
	        }
	        // Add and update new and existing attributes and listeners.
	        for (name in newAttrs) {
	            if (name in specialAttrs || oldAttrs[name] === newAttrs[name]) {
	                continue;
	            }
	            if (name.substr(0, 2) === 'on') {
	                element[name] = newAttrs[name];
	            }
	            else {
	                element.setAttribute(name, newAttrs[name]);
	            }
	        }
	        // Update the element `class` attribute.
	        if (oldAttrs.className !== newAttrs.className) {
	            if (newAttrs.className !== undefined) {
	                element.setAttribute('class', newAttrs.className);
	            }
	            else {
	                element.removeAttribute('class');
	            }
	        }
	        // Add the element `for` attribute.
	        if (oldAttrs.htmlFor !== newAttrs.htmlFor) {
	            if (newAttrs.htmlFor !== undefined) {
	                element.setAttribute('for', newAttrs.htmlFor);
	            }
	            else {
	                element.removeAttribute('for');
	            }
	        }
	        // Update the dataset values.
	        if (oldAttrs.dataset !== newAttrs.dataset) {
	            updateDataset(element, oldAttrs.dataset || {}, newAttrs.dataset || {});
	        }
	        // Update the inline styles.
	        if (oldAttrs.style !== newAttrs.style) {
	            updateStyle(element, oldAttrs.style || {}, newAttrs.style || {});
	        }
	    }
	    /**
	     * Add dataset values to a newly created HTML element.
	     */
	    function addDataset(element, dataset) {
	        for (var name_2 in dataset) {
	            element.setAttribute("data-" + name_2, dataset[name_2]);
	        }
	    }
	    /**
	     * Update the dataset values of an HTML element.
	     */
	    function updateDataset(element, oldDataset, newDataset) {
	        for (var name_3 in oldDataset) {
	            if (!(name_3 in newDataset)) {
	                element.removeAttribute("data-" + name_3);
	            }
	        }
	        for (var name_4 in newDataset) {
	            if (oldDataset[name_4] !== newDataset[name_4]) {
	                element.setAttribute("data-" + name_4, newDataset[name_4]);
	            }
	        }
	    }
	    /**
	     * Add inline style values to a newly created HTML element.
	     */
	    function addStyle(element, style) {
	        var elemStyle = element.style;
	        var name;
	        for (name in style) {
	            elemStyle[name] = style[name];
	        }
	    }
	    /**
	     * Update the inline style values of an HTML element.
	     */
	    function updateStyle(element, oldStyle, newStyle) {
	        var elemStyle = element.style;
	        var name;
	        for (name in oldStyle) {
	            if (!(name in newStyle)) {
	                elemStyle[name] = '';
	            }
	        }
	        for (name in newStyle) {
	            if (oldStyle[name] !== newStyle[name]) {
	                elemStyle[name] = newStyle[name];
	            }
	        }
	    }
	    /**
	     * Collect a mapping of keyed elements for the host content.
	     */
	    function collectKeys(host, content) {
	        var node = host.firstChild;
	        var keyMap = Object.create(null);
	        for (var _i = 0, content_1 = content; _i < content_1.length; _i++) {
	            var vNode = content_1[_i];
	            if (vNode.type === 'element' && vNode.attrs.key) {
	                keyMap[vNode.attrs.key] = { vNode: vNode, element: node };
	            }
	            node = node.nextSibling;
	        }
	        return keyMap;
	    }
	})(Private || (Private = {}));


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

	"use strict";
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var disposable_1 = __webpack_require__(209);
	var domutils_1 = __webpack_require__(192);
	var menu_1 = __webpack_require__(213);
	/**
	 * An object which implements a universal context menu.
	 *
	 * #### Notes
	 * The items shown in the context menu are determined by CSS selector
	 * matching against the DOM hierarchy at the site of the mouse click.
	 * This is similar in concept to how keyboard shortcuts are matched
	 * in the command registry.
	 */
	var ContextMenu = (function () {
	    /**
	     * Construct a new context menu.
	     *
	     * @param options - The options for initializing the menu.
	     */
	    function ContextMenu(options) {
	        this._idTick = 0;
	        this._items = [];
	        this.menu = new menu_1.Menu(options);
	    }
	    /**
	     * Add an item to the context menu.
	     *
	     * @param options - The options for creating the item.
	     *
	     * @returns A disposable which will remove the item from the menu.
	     */
	    ContextMenu.prototype.addItem = function (options) {
	        var _this = this;
	        // Create an item from the given options.
	        var item = Private.createItem(options, this._idTick++);
	        // Add the item to the internal array.
	        this._items.push(item);
	        // Return a disposable which will remove the item.
	        return new disposable_1.DisposableDelegate(function () {
	            algorithm_1.ArrayExt.removeFirstOf(_this._items, item);
	        });
	    };
	    /**
	     * Open the context menu in response to a `'contextmenu'` event.
	     *
	     * @param event - The `'contextmenu'` event of interest.
	     *
	     * @returns `true` if the menu was opened, or `false` if no items
	     *   matched the event and the menu was not opened.
	     *
	     * #### Notes
	     * This method will populate the context menu with items which match
	     * the propagation path of the event, then open the menu at the mouse
	     * position indicated by the event.
	     */
	    ContextMenu.prototype.open = function (event) {
	        var _this = this;
	        // Clear the current contents of the context menu.
	        this.menu.clearItems();
	        // Bail early if there are no items to match.
	        if (this._items.length === 0) {
	            return false;
	        }
	        // Find the matching items for the event.
	        var items = Private.matchItems(this._items, event);
	        // Bail if there are no matching items.
	        if (!items || items.length === 0) {
	            return false;
	        }
	        // Add the filtered items to the menu.
	        algorithm_1.each(items, function (item) { _this.menu.addItem(item); });
	        // Open the context menu at the current mouse position.
	        this.menu.open(event.clientX, event.clientY);
	        // Indicate success.
	        return true;
	    };
	    return ContextMenu;
	}());
	exports.ContextMenu = ContextMenu;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a normalized context menu item from an options object.
	     */
	    function createItem(options, id) {
	        var selector = validateSelector(options.selector);
	        var rank = options.rank !== undefined ? options.rank : Infinity;
	        return __assign({}, options, { selector: selector, rank: rank, id: id });
	    }
	    Private.createItem = createItem;
	    /**
	     * Find the items which match a context menu event.
	     *
	     * The results are sorted by DOM level, specificity, and rank.
	     */
	    function matchItems(items, event) {
	        // Look up the target of the event.
	        var target = event.target;
	        // Bail if there is no target.
	        if (!target) {
	            return null;
	        }
	        // Look up the current target of the event.
	        var currentTarget = event.currentTarget;
	        // Bail if there is no current target.
	        if (!currentTarget) {
	            return null;
	        }
	        // There are some third party libraries that cause the `target` to
	        // be detached from the DOM before Phosphor can process the event.
	        // If that happens, search for a new target node by point. If that
	        // node is still dangling, bail.
	        if (!currentTarget.contains(target)) {
	            target = document.elementFromPoint(event.clientX, event.clientY);
	            if (!target || !currentTarget.contains(target)) {
	                return null;
	            }
	        }
	        // Set up the result array.
	        var result = [];
	        // Copy the items array to allow in-place modification.
	        var availableItems = items.slice();
	        // Walk up the DOM hierarchy searching for matches.
	        while (target !== null) {
	            // Set up the match array for this DOM level.
	            var matches = [];
	            // Search the remaining items for matches.
	            for (var i = 0, n = availableItems.length; i < n; ++i) {
	                // Fetch the item.
	                var item = availableItems[i];
	                // Skip items which are already consumed.
	                if (!item) {
	                    continue;
	                }
	                // Skip items which do not match the element.
	                if (!domutils_1.Selector.matches(target, item.selector)) {
	                    continue;
	                }
	                // Add the matched item to the result for this DOM level.
	                matches.push(item);
	                // Mark the item as consumed.
	                availableItems[i] = null;
	            }
	            // Sort the matches for this level and add them to the results.
	            if (matches.length !== 0) {
	                matches.sort(itemCmp);
	                result.push.apply(result, matches);
	            }
	            // Stop searching at the limits of the DOM range.
	            if (target === currentTarget) {
	                break;
	            }
	            // Step to the parent DOM level.
	            target = target.parentElement;
	        }
	        // Return the matched and sorted results.
	        return result;
	    }
	    Private.matchItems = matchItems;
	    /**
	     * Validate the selector for a menu item.
	     *
	     * This returns the validated selector, or throws if the selector is
	     * invalid or contains commas.
	     */
	    function validateSelector(selector) {
	        if (selector.indexOf(',') !== -1) {
	            throw new Error("Selector cannot contain commas: " + selector);
	        }
	        if (!domutils_1.Selector.isValid(selector)) {
	            throw new Error("Invalid selector: " + selector);
	        }
	        return selector;
	    }
	    /**
	     * A sort comparison function for a context menu item.
	     */
	    function itemCmp(a, b) {
	        // Sort first based on selector specificity.
	        var s1 = domutils_1.Selector.calculateSpecificity(a.selector);
	        var s2 = domutils_1.Selector.calculateSpecificity(b.selector);
	        if (s1 !== s2) {
	            return s2 - s1;
	        }
	        // If specificities are equal, sort based on rank.
	        var r1 = a.rank;
	        var r2 = b.rank;
	        if (r1 !== r2) {
	            return r1 < r2 ? -1 : 1; // Infinity-safe
	        }
	        // When all else fails, sort by item id.
	        return a.id - b.id;
	    }
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var commands_1 = __webpack_require__(208);
	var coreutils_1 = __webpack_require__(6);
	var domutils_1 = __webpack_require__(192);
	var keyboard_1 = __webpack_require__(210);
	var messaging_1 = __webpack_require__(196);
	var signaling_1 = __webpack_require__(201);
	var virtualdom_1 = __webpack_require__(211);
	var widget_1 = __webpack_require__(202);
	/**
	 * A widget which displays items as a canonical menu.
	 */
	var Menu = (function (_super) {
	    __extends(Menu, _super);
	    /**
	     * Construct a new menu.
	     *
	     * @param options - The options for initializing the menu.
	     */
	    function Menu(options) {
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._childIndex = -1;
	        _this._activeIndex = -1;
	        _this._openTimerID = 0;
	        _this._closeTimerID = 0;
	        _this._items = [];
	        _this._childMenu = null;
	        _this._parentMenu = null;
	        _this._aboutToClose = new signaling_1.Signal(_this);
	        _this._menuRequested = new signaling_1.Signal(_this);
	        _this.addClass('p-Menu');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.commands = options.commands;
	        _this.renderer = options.renderer || Menu.defaultRenderer;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the menu.
	     */
	    Menu.prototype.dispose = function () {
	        this.close();
	        this._items.length = 0;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(Menu.prototype, "aboutToClose", {
	        /**
	         * A signal emitted just before the menu is closed.
	         *
	         * #### Notes
	         * This signal is emitted when the menu receives a `'close-request'`
	         * message, just before it removes itself from the DOM.
	         *
	         * This signal is not emitted if the menu is already detached from
	         * the DOM when it receives the `'close-request'` message.
	         */
	        get: function () {
	            return this._aboutToClose;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "menuRequested", {
	        /**
	         * A signal emitted when a new menu is requested by the user.
	         *
	         * #### Notes
	         * This signal is emitted whenever the user presses the right or left
	         * arrow keys, and a submenu cannot be opened or closed in response.
	         *
	         * This signal is useful when implementing menu bars in order to open
	         * the next or previous menu in response to a user key press.
	         *
	         * This signal is only emitted for the root menu in a hierarchy.
	         */
	        get: function () {
	            return this._menuRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "parentMenu", {
	        /**
	         * The parent menu of the menu.
	         *
	         * #### Notes
	         * This is `null` unless the menu is an open submenu.
	         */
	        get: function () {
	            return this._parentMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "childMenu", {
	        /**
	         * The child menu of the menu.
	         *
	         * #### Notes
	         * This is `null` unless the menu has an open submenu.
	         */
	        get: function () {
	            return this._childMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "rootMenu", {
	        /**
	         * The root menu of the menu hierarchy.
	         */
	        get: function () {
	            var menu = this;
	            while (menu._parentMenu) {
	                menu = menu._parentMenu;
	            }
	            return menu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "leafMenu", {
	        /**
	         * The leaf menu of the menu hierarchy.
	         */
	        get: function () {
	            var menu = this;
	            while (menu._childMenu) {
	                menu = menu._childMenu;
	            }
	            return menu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "contentNode", {
	        /**
	         * The menu content node.
	         *
	         * #### Notes
	         * This is the node which holds the menu item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-Menu-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "activeItem", {
	        /**
	         * Get the currently active menu item.
	         */
	        get: function () {
	            return this._items[this._activeIndex] || null;
	        },
	        /**
	         * Set the currently active menu item.
	         *
	         * #### Notes
	         * If the item cannot be activated, the item will be set to `null`.
	         */
	        set: function (value) {
	            this.activeIndex = value ? this._items.indexOf(value) : -1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "activeIndex", {
	        /**
	         * Get the index of the currently active menu item.
	         *
	         * #### Notes
	         * This will be `-1` if no menu item is active.
	         */
	        get: function () {
	            return this._activeIndex;
	        },
	        /**
	         * Set the index of the currently active menu item.
	         *
	         * #### Notes
	         * If the item cannot be activated, the index will be set to `-1`.
	         */
	        set: function (value) {
	            // Adjust the value for an out of range index.
	            if (value < 0 || value >= this._items.length) {
	                value = -1;
	            }
	            // Ensure the item can be activated.
	            if (value !== -1 && !Private.canActivate(this._items[value])) {
	                value = -1;
	            }
	            // Bail if the index will not change.
	            if (this._activeIndex === value) {
	                return;
	            }
	            // Update the active index.
	            this._activeIndex = value;
	            // schedule an update of the items.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "items", {
	        /**
	         * A read-only array of the menu items in the menu.
	         */
	        get: function () {
	            return this._items;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Activate the next selectable item in the menu.
	     *
	     * #### Notes
	     * If no item is selectable, the index will be set to `-1`.
	     */
	    Menu.prototype.activateNextItem = function () {
	        var n = this._items.length;
	        var ai = this._activeIndex;
	        var start = ai < n - 1 ? ai + 1 : 0;
	        var stop = start === 0 ? n - 1 : start - 1;
	        this.activeIndex = algorithm_1.ArrayExt.findFirstIndex(this._items, Private.canActivate, start, stop);
	    };
	    /**
	     * Activate the previous selectable item in the menu.
	     *
	     * #### Notes
	     * If no item is selectable, the index will be set to `-1`.
	     */
	    Menu.prototype.activatePreviousItem = function () {
	        var n = this._items.length;
	        var ai = this._activeIndex;
	        var start = ai <= 0 ? n - 1 : ai - 1;
	        var stop = start === n - 1 ? 0 : start + 1;
	        this.activeIndex = algorithm_1.ArrayExt.findLastIndex(this._items, Private.canActivate, start, stop);
	    };
	    /**
	     * Trigger the active menu item.
	     *
	     * #### Notes
	     * If the active item is a submenu, it will be opened and the first
	     * item will be activated.
	     *
	     * If the active item is a command, the command will be executed.
	     *
	     * If the menu is not attached, this is a no-op.
	     *
	     * If there is no active item, this is a no-op.
	     */
	    Menu.prototype.triggerActiveItem = function () {
	        // Bail if the menu is not attached.
	        if (!this.isAttached) {
	            return;
	        }
	        // Bail if there is no active item.
	        var item = this.activeItem;
	        if (!item) {
	            return;
	        }
	        // Cancel the pending timers.
	        this._cancelOpenTimer();
	        this._cancelCloseTimer();
	        // If the item is a submenu, open it.
	        if (item.type === 'submenu') {
	            this._openChildMenu(true);
	            return;
	        }
	        // Close the root menu before executing the command.
	        this.rootMenu.close();
	        // Execute the command for the item.
	        var command = item.command, args = item.args;
	        if (this.commands.isEnabled(command, args)) {
	            this.commands.execute(command, args);
	        }
	        else {
	            console.log("Command '" + command + "' is disabled.");
	        }
	    };
	    /**
	     * Add a menu item to the end of the menu.
	     *
	     * @param options - The options for creating the menu item.
	     *
	     * @returns The menu item added to the menu.
	     */
	    Menu.prototype.addItem = function (options) {
	        return this.insertItem(this._items.length, options);
	    };
	    /**
	     * Insert a menu item into the menu at the specified index.
	     *
	     * @param index - The index at which to insert the item.
	     *
	     * @param options - The options for creating the menu item.
	     *
	     * @returns The menu item added to the menu.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the items.
	     */
	    Menu.prototype.insertItem = function (index, options) {
	        // Close the menu if it's attached.
	        if (this.isAttached) {
	            this.close();
	        }
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Clamp the insert index to the array bounds.
	        var i = Math.max(0, Math.min(index, this._items.length));
	        // Create the item for the options.
	        var item = Private.createItem(this, options);
	        // Insert the item into the array.
	        algorithm_1.ArrayExt.insert(this._items, i, item);
	        // Schedule an update of the items.
	        this.update();
	        // Return the item added to the menu.
	        return item;
	    };
	    /**
	     * Remove an item from the menu.
	     *
	     * @param item - The item to remove from the menu.
	     *
	     * #### Notes
	     * This is a no-op if the item is not in the menu.
	     */
	    Menu.prototype.removeItem = function (item) {
	        this.removeItemAt(this._items.indexOf(item));
	    };
	    /**
	     * Remove the item at a given index from the menu.
	     *
	     * @param index - The index of the item to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    Menu.prototype.removeItemAt = function (index) {
	        // Close the menu if it's attached.
	        if (this.isAttached) {
	            this.close();
	        }
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Remove the item from the array.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Bail if the index is out of range.
	        if (!item) {
	            return;
	        }
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Remove all menu items from the menu.
	     */
	    Menu.prototype.clearItems = function () {
	        // Close the menu if it's attached.
	        if (this.isAttached) {
	            this.close();
	        }
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Bail if there is nothing to remove.
	        if (this._items.length === 0) {
	            return;
	        }
	        // Clear the items.
	        this._items.length = 0;
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Open the menu at the specified location.
	     *
	     * @param x - The client X coordinate of the menu location.
	     *
	     * @param y - The client Y coordinate of the menu location.
	     *
	     * @param options - The additional options for opening the menu.
	     *
	     * #### Notes
	     * The menu will be opened at the given location unless it will not
	     * fully fit on the screen. If it will not fit, it will be adjusted
	     * to fit naturally on the screen.
	     *
	     * This is a no-op if the menu is already attached to the DOM.
	     */
	    Menu.prototype.open = function (x, y, options) {
	        if (options === void 0) { options = {}; }
	        // Bail early if the menu is already attached.
	        if (this.isAttached) {
	            return;
	        }
	        // Extract the position options.
	        var forceX = options.forceX || false;
	        var forceY = options.forceY || false;
	        // Open the menu as a root menu.
	        Private.openRootMenu(this, x, y, forceX, forceY);
	        // Activate the menu to accept keyboard input.
	        this.activate();
	    };
	    /**
	     * Handle the DOM events for the menu.
	     *
	     * @param event - The DOM event sent to the menu.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the menu's DOM nodes. It should
	     * not be called directly by user code.
	     */
	    Menu.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseenter':
	                this._evtMouseEnter(event);
	                break;
	            case 'mouseleave':
	                this._evtMouseLeave(event);
	                break;
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    Menu.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('keydown', this);
	        this.node.addEventListener('mouseup', this);
	        this.node.addEventListener('mousemove', this);
	        this.node.addEventListener('mouseenter', this);
	        this.node.addEventListener('mouseleave', this);
	        this.node.addEventListener('contextmenu', this);
	        document.addEventListener('mousedown', this, true);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    Menu.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('keydown', this);
	        this.node.removeEventListener('mouseup', this);
	        this.node.removeEventListener('mousemove', this);
	        this.node.removeEventListener('mouseenter', this);
	        this.node.removeEventListener('mouseleave', this);
	        this.node.removeEventListener('contextmenu', this);
	        document.removeEventListener('mousedown', this, true);
	    };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     */
	    Menu.prototype.onActivateRequest = function (msg) {
	        if (this.isAttached) {
	            this.node.focus();
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    Menu.prototype.onUpdateRequest = function (msg) {
	        var items = this._items;
	        var renderer = this.renderer;
	        var activeIndex = this._activeIndex;
	        var collapsedFlags = Private.computeCollapsed(items);
	        var content = new Array(items.length);
	        for (var i = 0, n = items.length; i < n; ++i) {
	            var item = items[i];
	            var active = i === activeIndex;
	            var collapsed = collapsedFlags[i];
	            content[i] = renderer.renderItem({ item: item, active: active, collapsed: collapsed });
	        }
	        virtualdom_1.VirtualDOM.render(content, this.contentNode);
	    };
	    /**
	     * A message handler invoked on a `'close-request'` message.
	     */
	    Menu.prototype.onCloseRequest = function (msg) {
	        // Cancel the pending timers.
	        this._cancelOpenTimer();
	        this._cancelCloseTimer();
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Close any open child menu.
	        var childMenu = this._childMenu;
	        if (childMenu) {
	            this._childIndex = -1;
	            this._childMenu = null;
	            childMenu._parentMenu = null;
	            childMenu.close();
	        }
	        // Remove this menu from its parent and activate the parent.
	        var parentMenu = this._parentMenu;
	        if (parentMenu) {
	            this._parentMenu = null;
	            parentMenu._childIndex = -1;
	            parentMenu._childMenu = null;
	            parentMenu.activate();
	        }
	        // Emit the `aboutToClose` signal if the menu is attached.
	        if (this.isAttached) {
	            this._aboutToClose.emit(undefined);
	        }
	        // Finish closing the menu.
	        _super.prototype.onCloseRequest.call(this, msg);
	    };
	    /**
	     * Handle the `'keydown'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtKeyDown = function (event) {
	        // A menu handles all keydown events.
	        event.preventDefault();
	        event.stopPropagation();
	        // Fetch the key code for the event.
	        var kc = event.keyCode;
	        // Enter
	        if (kc === 13) {
	            this.triggerActiveItem();
	            return;
	        }
	        // Escape
	        if (kc === 27) {
	            this.close();
	            return;
	        }
	        // Left Arrow
	        if (kc === 37) {
	            if (this._parentMenu) {
	                this.close();
	            }
	            else {
	                this._menuRequested.emit('previous');
	            }
	            return;
	        }
	        // Up Arrow
	        if (kc === 38) {
	            this.activatePreviousItem();
	            return;
	        }
	        // Right Arrow
	        if (kc === 39) {
	            var item = this.activeItem;
	            if (item && item.type === 'submenu') {
	                this.triggerActiveItem();
	            }
	            else {
	                this.rootMenu._menuRequested.emit('next');
	            }
	            return;
	        }
	        // Down Arrow
	        if (kc === 40) {
	            this.activateNextItem();
	            return;
	        }
	        // Get the pressed key character.
	        var key = keyboard_1.getKeyboardLayout().keyForKeydownEvent(event);
	        // Bail if the key is not valid.
	        if (!key) {
	            return;
	        }
	        // Search for the next best matching mnemonic item.
	        var start = this._activeIndex + 1;
	        var result = Private.findMnemonic(this._items, key, start);
	        // Handle the requested mnemonic based on the search results.
	        // If exactly one mnemonic is matched, that item is triggered.
	        // Otherwise, the next mnemonic is activated if available,
	        // followed by the auto mnemonic if available.
	        if (result.index !== -1 && !result.multiple) {
	            this.activeIndex = result.index;
	            this.triggerActiveItem();
	        }
	        else if (result.index !== -1) {
	            this.activeIndex = result.index;
	        }
	        else if (result.auto !== -1) {
	            this.activeIndex = result.auto;
	        }
	    };
	    /**
	     * Handle the `'mouseup'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseUp = function (event) {
	        if (event.button !== 0) {
	            return;
	        }
	        event.preventDefault();
	        event.stopPropagation();
	        this.triggerActiveItem();
	    };
	    /**
	     * Handle the `'mousemove'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseMove = function (event) {
	        // Hit test the item nodes for the item under the mouse.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return domutils_1.ElementExt.hitTest(node, event.clientX, event.clientY);
	        });
	        // Bail early if the mouse is already over the active index.
	        if (index === this._activeIndex) {
	            return;
	        }
	        // Update and coerce the active index.
	        this.activeIndex = index;
	        index = this.activeIndex;
	        // If the index is the current child index, cancel the timers.
	        if (index === this._childIndex) {
	            this._cancelOpenTimer();
	            this._cancelCloseTimer();
	            return;
	        }
	        // If a child menu is currently open, start the close timer.
	        if (this._childIndex !== -1) {
	            this._startCloseTimer();
	        }
	        // Cancel the open timer to give a full delay for opening.
	        this._cancelOpenTimer();
	        // Bail if the active item is not a valid submenu item.
	        var item = this.activeItem;
	        if (!item || item.type !== 'submenu' || !item.submenu) {
	            return;
	        }
	        // Start the open timer to open the active item submenu.
	        this._startOpenTimer();
	    };
	    /**
	     * Handle the `'mouseenter'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseEnter = function (event) {
	        // Synchronize the active ancestor items.
	        for (var menu = this._parentMenu; menu; menu = menu._parentMenu) {
	            menu._cancelOpenTimer();
	            menu._cancelCloseTimer();
	            menu.activeIndex = menu._childIndex;
	        }
	    };
	    /**
	     * Handle the `'mouseleave'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseLeave = function (event) {
	        // Cancel any pending submenu opening.
	        this._cancelOpenTimer();
	        // If there is no open child menu, just reset the active index.
	        if (!this._childMenu) {
	            this.activeIndex = -1;
	            return;
	        }
	        // If the mouse is over the child menu, cancel the close timer.
	        var clientX = event.clientX, clientY = event.clientY;
	        if (domutils_1.ElementExt.hitTest(this._childMenu.node, clientX, clientY)) {
	            this._cancelCloseTimer();
	            return;
	        }
	        // Otherwise, reset the active index and start the close timer.
	        this.activeIndex = -1;
	        this._startCloseTimer();
	    };
	    /**
	     * Handle the `'mousedown'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the document node.
	     */
	    Menu.prototype._evtMouseDown = function (event) {
	        // Bail if the menu is not a root menu.
	        if (this._parentMenu) {
	            return;
	        }
	        // The mouse button which is pressed is irrelevant. If the press
	        // is not on a menu, the entire hierarchy is closed and the event
	        // is allowed to propagate. This allows other code to act on the
	        // event, such as focusing the clicked element.
	        if (Private.hitTestMenus(this, event.clientX, event.clientY)) {
	            event.preventDefault();
	            event.stopPropagation();
	        }
	        else {
	            this.close();
	        }
	    };
	    /**
	     * Open the child menu at the active index immediately.
	     *
	     * If a different child menu is already open, it will be closed,
	     * even if the active item is not a valid submenu.
	     */
	    Menu.prototype._openChildMenu = function (activateFirst) {
	        if (activateFirst === void 0) { activateFirst = false; }
	        // If the item is not a valid submenu, close the child menu.
	        var item = this.activeItem;
	        if (!item || item.type !== 'submenu' || !item.submenu) {
	            this._closeChildMenu();
	            return;
	        }
	        // Do nothing if the child menu will not change.
	        var submenu = item.submenu;
	        if (submenu === this._childMenu) {
	            return;
	        }
	        // Ensure the current child menu is closed.
	        this._closeChildMenu();
	        // Update the private child state.
	        this._childMenu = submenu;
	        this._childIndex = this._activeIndex;
	        // Set the parent menu reference for the child.
	        submenu._parentMenu = this;
	        // Ensure the menu is updated and lookup the item node.
	        messaging_1.MessageLoop.sendMessage(this, widget_1.Widget.Msg.UpdateRequest);
	        var itemNode = this.contentNode.children[this._activeIndex];
	        // Open the submenu at the active node.
	        Private.openSubmenu(submenu, itemNode);
	        // Activate the first item if desired.
	        if (activateFirst) {
	            submenu.activeIndex = -1;
	            submenu.activateNextItem();
	        }
	        // Activate the child menu.
	        submenu.activate();
	    };
	    /**
	     * Close the child menu immediately.
	     *
	     * This is a no-op if a child menu is not open.
	     */
	    Menu.prototype._closeChildMenu = function () {
	        if (this._childMenu) {
	            this._childMenu.close();
	        }
	    };
	    /**
	     * Start the open timer, unless it is already pending.
	     */
	    Menu.prototype._startOpenTimer = function () {
	        var _this = this;
	        if (this._openTimerID === 0) {
	            this._openTimerID = setTimeout(function () {
	                _this._openTimerID = 0;
	                _this._openChildMenu();
	            }, Private.TIMER_DELAY);
	        }
	    };
	    /**
	     * Start the close timer, unless it is already pending.
	     */
	    Menu.prototype._startCloseTimer = function () {
	        var _this = this;
	        if (this._closeTimerID === 0) {
	            this._closeTimerID = setTimeout(function () {
	                _this._closeTimerID = 0;
	                _this._closeChildMenu();
	            }, Private.TIMER_DELAY);
	        }
	    };
	    /**
	     * Cancel the open timer, if the timer is pending.
	     */
	    Menu.prototype._cancelOpenTimer = function () {
	        if (this._openTimerID !== 0) {
	            clearTimeout(this._openTimerID);
	            this._openTimerID = 0;
	        }
	    };
	    /**
	     * Cancel the close timer, if the timer is pending.
	     */
	    Menu.prototype._cancelCloseTimer = function () {
	        if (this._closeTimerID !== 0) {
	            clearTimeout(this._closeTimerID);
	            this._closeTimerID = 0;
	        }
	    };
	    return Menu;
	}(widget_1.Widget));
	exports.Menu = Menu;
	/**
	 * The namespace for the `Menu` class statics.
	 */
	(function (Menu) {
	    /**
	     * The default implementation of `IRenderer`.
	     *
	     * #### Notes
	     * Subclasses are free to reimplement rendering methods as needed.
	     */
	    var Renderer = (function () {
	        /**
	         * Construct a new renderer.
	         */
	        function Renderer() {
	        }
	        /**
	         * Render the virtual element for a menu item.
	         *
	         * @param data - The data to use for rendering the item.
	         *
	         * @returns A virtual element representing the item.
	         */
	        Renderer.prototype.renderItem = function (data) {
	            var className = this.createItemClass(data);
	            var dataset = this.createItemDataset(data);
	            return (virtualdom_1.h.li({ className: className, dataset: dataset }, this.renderIcon(data), this.renderLabel(data), this.renderShortcut(data), this.renderSubmenu(data)));
	        };
	        /**
	         * Render the icon element for a menu item.
	         *
	         * @param data - The data to use for rendering the icon.
	         *
	         * @returns A virtual element representing the item icon.
	         */
	        Renderer.prototype.renderIcon = function (data) {
	            var className = this.createIconClass(data);
	            return virtualdom_1.h.div({ className: className }, data.item.iconLabel);
	        };
	        /**
	         * Render the label element for a menu item.
	         *
	         * @param data - The data to use for rendering the label.
	         *
	         * @returns A virtual element representing the item label.
	         */
	        Renderer.prototype.renderLabel = function (data) {
	            var content = this.formatLabel(data);
	            return virtualdom_1.h.div({ className: 'p-Menu-itemLabel' }, content);
	        };
	        /**
	         * Render the shortcut element for a menu item.
	         *
	         * @param data - The data to use for rendering the shortcut.
	         *
	         * @returns A virtual element representing the item shortcut.
	         */
	        Renderer.prototype.renderShortcut = function (data) {
	            var content = this.formatShortcut(data);
	            return virtualdom_1.h.div({ className: 'p-Menu-itemShortcut' }, content);
	        };
	        /**
	         * Render the submenu icon element for a menu item.
	         *
	         * @param data - The data to use for rendering the submenu icon.
	         *
	         * @returns A virtual element representing the submenu icon.
	         */
	        Renderer.prototype.renderSubmenu = function (data) {
	            return virtualdom_1.h.div({ className: 'p-Menu-itemSubmenuIcon' });
	        };
	        /**
	         * Create the class name for the menu item.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the menu item.
	         */
	        Renderer.prototype.createItemClass = function (data) {
	            // Setup the initial class name.
	            var name = 'p-Menu-item';
	            // Add the boolean state classes.
	            if (!data.item.isEnabled) {
	                name += ' p-mod-disabled';
	            }
	            if (data.item.isToggled) {
	                name += ' p-mod-toggled';
	            }
	            if (!data.item.isVisible) {
	                name += ' p-mod-hidden';
	            }
	            if (data.active) {
	                name += ' p-mod-active';
	            }
	            if (data.collapsed) {
	                name += ' p-mod-collapsed';
	            }
	            // Add the extra class.
	            var extra = data.item.className;
	            if (extra) {
	                name += " " + extra;
	            }
	            // Return the complete class name.
	            return name;
	        };
	        /**
	         * Create the dataset for the menu item.
	         *
	         * @param data - The data to use for creating the dataset.
	         *
	         * @returns The dataset for the menu item.
	         */
	        Renderer.prototype.createItemDataset = function (data) {
	            var result;
	            var _a = data.item, type = _a.type, command = _a.command, dataset = _a.dataset;
	            if (type === 'command') {
	                result = __assign({}, dataset, { type: type, command: command });
	            }
	            else {
	                result = __assign({}, dataset, { type: type });
	            }
	            return result;
	        };
	        /**
	         * Create the class name for the menu item icon.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the item icon.
	         */
	        Renderer.prototype.createIconClass = function (data) {
	            var name = 'p-Menu-itemIcon';
	            var extra = data.item.iconClass;
	            return extra ? name + " " + extra : name;
	        };
	        /**
	         * Create the render content for the label node.
	         *
	         * @param data - The data to use for the label content.
	         *
	         * @returns The content to add to the label node.
	         */
	        Renderer.prototype.formatLabel = function (data) {
	            // Fetch the label text and mnemonic index.
	            var _a = data.item, label = _a.label, mnemonic = _a.mnemonic;
	            // If the index is out of range, do not modify the label.
	            if (mnemonic < 0 || mnemonic >= label.length) {
	                return label;
	            }
	            // Split the label into parts.
	            var prefix = label.slice(0, mnemonic);
	            var suffix = label.slice(mnemonic + 1);
	            var char = label[mnemonic];
	            // Wrap the mnemonic character in a span.
	            var span = virtualdom_1.h.span({ className: 'p-Menu-itemMnemonic' }, char);
	            // Return the content parts.
	            return [prefix, span, suffix];
	        };
	        /**
	         * Create the render content for the shortcut node.
	         *
	         * @param data - The data to use for the shortcut content.
	         *
	         * @returns The content to add to the shortcut node.
	         */
	        Renderer.prototype.formatShortcut = function (data) {
	            var kb = data.item.keyBinding;
	            return kb ? kb.keys.map(Private.formatKeystroke).join(', ') : null;
	        };
	        return Renderer;
	    }());
	    Menu.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    Menu.defaultRenderer = new Renderer();
	})(Menu = exports.Menu || (exports.Menu = {}));
	exports.Menu = Menu;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The ms delay for opening and closing a submenu.
	     */
	    Private.TIMER_DELAY = 300;
	    /**
	     * The horizontal pixel overlap for an open submenu.
	     */
	    Private.SUBMENU_OVERLAP = 3;
	    /**
	     * Create the DOM node for a menu.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = 'p-Menu-content';
	        node.appendChild(content);
	        node.tabIndex = -1;
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Test whether a menu item can be activated.
	     */
	    function canActivate(item) {
	        return item.type !== 'separator' && item.isEnabled && item.isVisible;
	    }
	    Private.canActivate = canActivate;
	    /**
	     * Create a new menu item for an owner menu.
	     */
	    function createItem(owner, options) {
	        return new MenuItem(owner.commands, options);
	    }
	    Private.createItem = createItem;
	    /**
	     * Format a keystroke for display on the local system.
	     */
	    function formatKeystroke(keystroke) {
	        var mods = '';
	        var parts = commands_1.CommandRegistry.parseKeystroke(keystroke);
	        if (domutils_1.Platform.IS_MAC) {
	            if (parts.ctrl) {
	                mods += '\u2303 ';
	            }
	            if (parts.alt) {
	                mods += '\u2325 ';
	            }
	            if (parts.shift) {
	                mods += '\u21E7 ';
	            }
	            if (parts.cmd) {
	                mods += '\u2318 ';
	            }
	        }
	        else {
	            if (parts.ctrl) {
	                mods += 'Ctrl+';
	            }
	            if (parts.alt) {
	                mods += 'Alt+';
	            }
	            if (parts.shift) {
	                mods += 'Shift+';
	            }
	        }
	        return mods + parts.key;
	    }
	    Private.formatKeystroke = formatKeystroke;
	    /**
	     * Hit test a menu hierarchy starting at the given root.
	     */
	    function hitTestMenus(menu, x, y) {
	        for (var temp = menu; temp; temp = temp.childMenu) {
	            if (domutils_1.ElementExt.hitTest(temp.node, x, y)) {
	                return true;
	            }
	        }
	        return false;
	    }
	    Private.hitTestMenus = hitTestMenus;
	    /**
	     * Compute which extra separator items should be collapsed.
	     */
	    function computeCollapsed(items) {
	        // Allocate the return array and fill it with `false`.
	        var result = new Array(items.length);
	        algorithm_1.ArrayExt.fill(result, false);
	        // Collapse the leading separators.
	        var k1 = 0;
	        var n = items.length;
	        for (; k1 < n; ++k1) {
	            var item = items[k1];
	            if (!item.isVisible) {
	                continue;
	            }
	            if (item.type !== 'separator') {
	                break;
	            }
	            result[k1] = true;
	        }
	        // Hide the trailing separators.
	        var k2 = n - 1;
	        for (; k2 >= 0; --k2) {
	            var item = items[k2];
	            if (!item.isVisible) {
	                continue;
	            }
	            if (item.type !== 'separator') {
	                break;
	            }
	            result[k2] = true;
	        }
	        // Hide the remaining consecutive separators.
	        var hide = false;
	        while (++k1 < k2) {
	            var item = items[k1];
	            if (!item.isVisible) {
	                continue;
	            }
	            if (item.type !== 'separator') {
	                hide = false;
	            }
	            else if (hide) {
	                result[k1] = true;
	            }
	            else {
	                hide = true;
	            }
	        }
	        // Return the resulting flags.
	        return result;
	    }
	    Private.computeCollapsed = computeCollapsed;
	    /**
	     * Open a menu as a root menu at the target location.
	     */
	    function openRootMenu(menu, x, y, forceX, forceY) {
	        // Ensure the menu is updated before attaching and measuring.
	        messaging_1.MessageLoop.sendMessage(menu, widget_1.Widget.Msg.UpdateRequest);
	        // Get the current position and size of the main viewport.
	        var px = window.pageXOffset;
	        var py = window.pageYOffset;
	        var cw = document.documentElement.clientWidth;
	        var ch = document.documentElement.clientHeight;
	        // Compute the maximum allowed height for the menu.
	        var maxHeight = ch - (forceY ? y : 0);
	        // Fetch common variables.
	        var node = menu.node;
	        var style = node.style;
	        // Clear the menu geometry and prepare it for measuring.
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	        style.visibility = 'hidden';
	        style.maxHeight = maxHeight + "px";
	        // Attach the menu to the document.
	        widget_1.Widget.attach(menu, document.body);
	        // Measure the size of the menu.
	        var _a = node.getBoundingClientRect(), width = _a.width, height = _a.height;
	        // Adjust the X position of the menu to fit on-screen.
	        if (!forceX && (x + width > px + cw)) {
	            x = px + cw - width;
	        }
	        // Adjust the Y position of the menu to fit on-screen.
	        if (!forceY && (y + height > py + ch)) {
	            if (y > py + ch) {
	                y = py + ch - height;
	            }
	            else {
	                y = y - height;
	            }
	        }
	        // Update the position of the menu to the computed position.
	        style.top = Math.max(0, y) + "px";
	        style.left = Math.max(0, x) + "px";
	        // Finally, make the menu visible on the screen.
	        style.visibility = '';
	    }
	    Private.openRootMenu = openRootMenu;
	    /**
	     * Open a menu as a submenu using an item node for positioning.
	     */
	    function openSubmenu(submenu, itemNode) {
	        // Ensure the menu is updated before opening.
	        messaging_1.MessageLoop.sendMessage(submenu, widget_1.Widget.Msg.UpdateRequest);
	        // Get the current position and size of the main viewport.
	        var px = window.pageXOffset;
	        var py = window.pageYOffset;
	        var cw = document.documentElement.clientWidth;
	        var ch = document.documentElement.clientHeight;
	        // Compute the maximum allowed height for the menu.
	        var maxHeight = ch;
	        // Fetch common variables.
	        var node = submenu.node;
	        var style = node.style;
	        // Clear the menu geometry and prepare it for measuring.
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	        style.visibility = 'hidden';
	        style.maxHeight = maxHeight + "px";
	        // Attach the menu to the document.
	        widget_1.Widget.attach(submenu, document.body);
	        // Measure the size of the menu.
	        var _a = node.getBoundingClientRect(), width = _a.width, height = _a.height;
	        // Compute the box sizing for the menu.
	        var box = domutils_1.ElementExt.boxSizing(submenu.node);
	        // Get the bounding rect for the target item node.
	        var itemRect = itemNode.getBoundingClientRect();
	        // Compute the target X position.
	        var x = itemRect.right - Private.SUBMENU_OVERLAP;
	        // Adjust the X position to fit on the screen.
	        if (x + width > px + cw) {
	            x = itemRect.left + Private.SUBMENU_OVERLAP - width;
	        }
	        // Compute the target Y position.
	        var y = itemRect.top - box.borderTop - box.paddingTop;
	        // Adjust the Y position to fit on the screen.
	        if (y + height > py + ch) {
	            y = itemRect.bottom + box.borderBottom + box.paddingBottom - height;
	        }
	        // Update the position of the menu to the computed position.
	        style.top = Math.max(0, y) + "px";
	        style.left = Math.max(0, x) + "px";
	        // Finally, make the menu visible on the screen.
	        style.visibility = '';
	    }
	    Private.openSubmenu = openSubmenu;
	    /**
	     * Find the best matching mnemonic item.
	     *
	     * The search starts at the given index and wraps around.
	     */
	    function findMnemonic(items, key, start) {
	        // Setup the result variables.
	        var index = -1;
	        var auto = -1;
	        var multiple = false;
	        // Normalize the key to upper case.
	        var upperKey = key.toUpperCase();
	        // Search the items from the given start index.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Compute the wrapped index.
	            var k = (i + start) % n;
	            // Lookup the item
	            var item = items[k];
	            // Ignore items which cannot be activated.
	            if (!canActivate(item)) {
	                continue;
	            }
	            // Ignore items with an empty label.
	            var label = item.label;
	            if (label.length === 0) {
	                continue;
	            }
	            // Lookup the mnemonic index for the label.
	            var mn = item.mnemonic;
	            // Handle a valid mnemonic index.
	            if (mn >= 0 && mn < label.length) {
	                if (label[mn].toUpperCase() === upperKey) {
	                    if (index === -1) {
	                        index = k;
	                    }
	                    else {
	                        multiple = true;
	                    }
	                }
	                continue;
	            }
	            // Finally, handle the auto index if possible.
	            if (auto === -1 && label[0].toUpperCase() === upperKey) {
	                auto = k;
	            }
	        }
	        // Return the search results.
	        return { index: index, multiple: multiple, auto: auto };
	    }
	    Private.findMnemonic = findMnemonic;
	    /**
	     * A concrete implementation of `Menu.IItem`.
	     */
	    var MenuItem = (function () {
	        /**
	         * Construct a new menu item.
	         */
	        function MenuItem(commands, options) {
	            this._commands = commands;
	            this.type = options.type || 'command';
	            this.command = options.command || '';
	            this.args = options.args || coreutils_1.JSONExt.emptyObject;
	            this.submenu = options.submenu || null;
	        }
	        Object.defineProperty(MenuItem.prototype, "label", {
	            /**
	             * The display label for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.label(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.label;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "mnemonic", {
	            /**
	             * The mnemonic index for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.mnemonic(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.mnemonic;
	                }
	                return -1;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "icon", {
	            /**
	             * @deprecated Use `iconClass` instead.
	             */
	            get: function () {
	                return this.iconClass;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "iconClass", {
	            /**
	             * The icon class for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.iconClass(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.iconClass;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "iconLabel", {
	            /**
	             * The icon label for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.iconLabel(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.iconLabel;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "caption", {
	            /**
	             * The display caption for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.caption(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.caption;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "className", {
	            /**
	             * The extra class name for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.className(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.className;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "dataset", {
	            /**
	             * The dataset for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.dataset(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.dataset;
	                }
	                return {};
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "isEnabled", {
	            /**
	             * Whether the menu item is enabled.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.isEnabled(this.command, this.args);
	                }
	                if (this.type === 'submenu') {
	                    return this.submenu !== null;
	                }
	                return true;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "isToggled", {
	            /**
	             * Whether the menu item is toggled.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.isToggled(this.command, this.args);
	                }
	                return false;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "isVisible", {
	            /**
	             * Whether the menu item is visible.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.isVisible(this.command, this.args);
	                }
	                if (this.type === 'submenu') {
	                    return this.submenu !== null;
	                }
	                return true;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "keyBinding", {
	            /**
	             * The key binding for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    var _a = this, command_1 = _a.command, args_1 = _a.args;
	                    return algorithm_1.ArrayExt.findLastValue(this._commands.keyBindings, function (kb) {
	                        return kb.command === command_1 && coreutils_1.JSONExt.deepEqual(kb.args, args_1);
	                    }) || null;
	                }
	                return null;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        return MenuItem;
	    }());
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var messaging_1 = __webpack_require__(196);
	var boxengine_1 = __webpack_require__(173);
	var layout_1 = __webpack_require__(200);
	var widget_1 = __webpack_require__(202);
	/**
	 * A layout which provides a flexible docking arrangement.
	 *
	 * #### Notes
	 * The consumer of this layout is repsonsible for handling all signals
	 * from the generated tab bars and managing the visibility of widgets
	 * and tab bars as needed.
	 */
	var DockLayout = (function (_super) {
	    __extends(DockLayout, _super);
	    /**
	     * Construct a new dock layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function DockLayout(options) {
	        var _this = _super.call(this) || this;
	        _this._spacing = 4;
	        _this._dirty = false;
	        _this._root = null;
	        _this._box = null;
	        _this._items = new Map();
	        _this.renderer = options.renderer;
	        if (options.spacing !== undefined) {
	            _this._spacing = Private.clampSpacing(options.spacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This will clear and dispose all widgets in the layout.
	     */
	    DockLayout.prototype.dispose = function () {
	        // Get an iterator over the widgets in the layout.
	        var widgets = this.iter();
	        // Dispose of the layout items.
	        this._items.forEach(function (item) { item.dispose(); });
	        // Clear the layout state before disposing the widgets.
	        this._box = null;
	        this._root = null;
	        this._items.clear();
	        // Dispose of the widgets contained in the old layout root.
	        algorithm_1.each(widgets, function (widget) { widget.dispose(); });
	        // Dispose of the base class.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(DockLayout.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the dock layout.
	         */
	        get: function () {
	            return this._spacing;
	        },
	        /**
	         * Set the inter-element spacing for the dock layout.
	         */
	        set: function (value) {
	            value = Private.clampSpacing(value);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockLayout.prototype, "isEmpty", {
	        /**
	         * Whether the dock layout is empty.
	         */
	        get: function () {
	            return this._root === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over all widgets in the layout.
	     *
	     * @returns A new iterator over the widgets in the layout.
	     *
	     * #### Notes
	     * This iterator includes the generated tab bars.
	     */
	    DockLayout.prototype.iter = function () {
	        return this._root ? this._root.iterAllWidgets() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the user widgets in the layout.
	     *
	     * @returns A new iterator over the user widgets in the layout.
	     *
	     * #### Notes
	     * This iterator does not include the generated tab bars.
	     */
	    DockLayout.prototype.widgets = function () {
	        return this._root ? this._root.iterUserWidgets() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the selected widgets in the layout.
	     *
	     * @returns A new iterator over the selected user widgets.
	     *
	     * #### Notes
	     * This iterator yields the widgets corresponding to the current tab
	     * of each tab bar in the layout.
	     */
	    DockLayout.prototype.selectedWidgets = function () {
	        return this._root ? this._root.iterSelectedWidgets() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the tab bars in the layout.
	     *
	     * @returns A new iterator over the tab bars in the layout.
	     *
	     * #### Notes
	     * This iterator does not include the user widgets.
	     */
	    DockLayout.prototype.tabBars = function () {
	        return this._root ? this._root.iterTabBars() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the handles in the layout.
	     *
	     * @returns A new iterator over the handles in the layout.
	     */
	    DockLayout.prototype.handles = function () {
	        return this._root ? this._root.iterHandles() : algorithm_1.empty();
	    };
	    /**
	     * Move a handle to the given offset position.
	     *
	     * @param handle - The handle to move.
	     *
	     * @param offsetX - The desired offset X position of the handle.
	     *
	     * @param offsetY - The desired offset Y position of the handle.
	     *
	     * #### Notes
	     * If the given handle is not contained in the layout, this is no-op.
	     *
	     * The handle will be moved as close as possible to the desired
	     * position without violating any of the layout constraints.
	     *
	     * Only one of the coordinates is used depending on the orientation
	     * of the handle. This method accepts both coordinates to make it
	     * easy to invoke from a mouse move event without needing to know
	     * the handle orientation.
	     */
	    DockLayout.prototype.moveHandle = function (handle, offsetX, offsetY) {
	        // Bail early if there is no root or if the handle is hidden.
	        if (!this._root || handle.classList.contains('p-mod-hidden')) {
	            return;
	        }
	        // Lookup the split node for the handle.
	        var data = this._root.findSplitNode(handle);
	        if (!data) {
	            return;
	        }
	        // Compute the desired delta movement for the handle.
	        var delta;
	        if (data.node.orientation === 'horizontal') {
	            delta = offsetX - handle.offsetLeft;
	        }
	        else {
	            delta = offsetY - handle.offsetTop;
	        }
	        // Bail if there is no handle movement.
	        if (delta === 0) {
	            return;
	        }
	        // Prevent sibling resizing unless needed.
	        data.node.holdSizes();
	        // Adjust the sizers to reflect the handle movement.
	        boxengine_1.BoxEngine.adjust(data.node.sizers, data.index, delta);
	        // Update the layout of the widgets.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Save the current configuration of the dock layout.
	     *
	     * @returns A new config object for the current layout state.
	     *
	     * #### Notes
	     * The return value can be provided to the `restoreLayout` method
	     * in order to restore the layout to its current configuration.
	     */
	    DockLayout.prototype.saveLayout = function () {
	        // Bail early if there is no root.
	        if (!this._root) {
	            return { main: null };
	        }
	        // Hold the current sizes in the layout tree.
	        this._root.holdAllSizes();
	        // Return the layout config.
	        return { main: this._root.createConfig() };
	    };
	    /**
	     * Restore the layout to a previously saved configuration.
	     *
	     * @param config - The layout configuration to restore.
	     *
	     * #### Notes
	     * Widgets which currently belong to the layout but which are not
	     * contained in the config will be unparented.
	     */
	    DockLayout.prototype.restoreLayout = function (config) {
	        var _this = this;
	        // Create the widget set for validating the config.
	        var widgetSet = new Set();
	        // Normalize the main area config and collect the widgets.
	        var mainConfig;
	        if (config.main) {
	            mainConfig = Private.normalizeAreaConfig(config.main, widgetSet);
	        }
	        else {
	            mainConfig = null;
	        }
	        // Create iterators over the old content.
	        var oldWidgets = this.widgets();
	        var oldTabBars = this.tabBars();
	        var oldHandles = this.handles();
	        // Clear the root before removing the old content.
	        this._root = null;
	        // Unparent the old widgets which are not in the new config.
	        algorithm_1.each(oldWidgets, function (widget) {
	            if (!widgetSet.has(widget)) {
	                widget.parent = null;
	            }
	        });
	        // Dispose of the old tab bars.
	        algorithm_1.each(oldTabBars, function (tabBar) {
	            tabBar.dispose();
	        });
	        // Remove the old handles.
	        algorithm_1.each(oldHandles, function (handle) {
	            if (handle.parentNode) {
	                handle.parentNode.removeChild(handle);
	            }
	        });
	        // Reparent the new widgets to the current parent.
	        widgetSet.forEach(function (widget) {
	            widget.parent = _this.parent;
	        });
	        // Create the root node for the new config.
	        if (mainConfig) {
	            this._root = Private.realizeAreaConfig(mainConfig, {
	                createTabBar: function () { return _this._createTabBar(); },
	                createHandle: function () { return _this._createHandle(); }
	            });
	        }
	        else {
	            this._root = null;
	        }
	        // If there is no parent, there is nothing more to do.
	        if (!this.parent) {
	            return;
	        }
	        // Attach the new widgets to the parent.
	        widgetSet.forEach(function (widget) {
	            _this.attachWidget(widget);
	        });
	        // Post a fit request to the parent.
	        this.parent.fit();
	    };
	    /**
	     * Add a widget to the dock layout.
	     *
	     * @param widget - The widget to add to the dock layout.
	     *
	     * @param options - The additional options for adding the widget.
	     *
	     * #### Notes
	     * The widget will be moved if it is already contained in the layout.
	     *
	     * An error will be thrown if the reference widget is invalid.
	     */
	    DockLayout.prototype.addWidget = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        // Parse the options.
	        var ref = options.ref || null;
	        var mode = options.mode || 'tab-after';
	        // Find the tab node which holds the reference widget.
	        var refNode = null;
	        if (this._root && ref) {
	            refNode = this._root.findTabNode(ref);
	        }
	        // Throw an error if the reference widget is invalid.
	        if (ref && !refNode) {
	            throw new Error('Reference widget is not in the layout.');
	        }
	        // Reparent the widget to the current layout parent.
	        widget.parent = this.parent;
	        // Insert the widget according to the insert mode.
	        switch (mode) {
	            case 'tab-after':
	                this._insertTab(widget, ref, refNode, true);
	                break;
	            case 'tab-before':
	                this._insertTab(widget, ref, refNode, false);
	                break;
	            case 'split-top':
	                this._insertSplit(widget, ref, refNode, 'vertical', false);
	                break;
	            case 'split-left':
	                this._insertSplit(widget, ref, refNode, 'horizontal', false);
	                break;
	            case 'split-right':
	                this._insertSplit(widget, ref, refNode, 'horizontal', true);
	                break;
	            case 'split-bottom':
	                this._insertSplit(widget, ref, refNode, 'vertical', true);
	                break;
	        }
	        // Do nothing else if there is no parent widget.
	        if (!this.parent) {
	            return;
	        }
	        // Ensure the widget is attached to the parent widget.
	        this.attachWidget(widget);
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Remove a widget from the layout.
	     *
	     * @param widget - The widget to remove from the layout.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     */
	    DockLayout.prototype.removeWidget = function (widget) {
	        // Remove the widget from its current layout location.
	        this._removeWidget(widget);
	        // Do nothing else if there is no parent widget.
	        if (!this.parent) {
	            return;
	        }
	        // Detach the widget from the parent widget.
	        this.detachWidget(widget);
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Find the tab area which contains the given client position.
	     *
	     * @param clientX - The client X position of interest.
	     *
	     * @param clientY - The client Y position of interest.
	     *
	     * @returns The geometry of the tab area at the given position, or
	     *   `null` if there is no tab area at the given position.
	     */
	    DockLayout.prototype.hitTestTabAreas = function (clientX, clientY) {
	        // Bail early if hit testing cannot produce valid results.
	        if (!this._root || !this.parent || !this.parent.isVisible) {
	            return null;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Convert from client to local coordinates.
	        var rect = this.parent.node.getBoundingClientRect();
	        var x = clientX - rect.left - this._box.borderLeft;
	        var y = clientY - rect.top - this._box.borderTop;
	        // Find the tab layout node at the local position.
	        var tabNode = this._root.hitTestTabNodes(x, y);
	        // Bail if a tab layout node was not found.
	        if (!tabNode) {
	            return null;
	        }
	        // Extract the data from the tab node.
	        var tabBar = tabNode.tabBar, top = tabNode.top, left = tabNode.left, width = tabNode.width, height = tabNode.height;
	        // Compute the right and bottom edges of the tab area.
	        var borderWidth = this._box.borderLeft + this._box.borderRight;
	        var borderHeight = this._box.borderTop + this._box.borderBottom;
	        var right = rect.width - borderWidth - (left + width);
	        var bottom = rect.height - borderHeight - (top + height);
	        // Return the hit test results.
	        return { tabBar: tabBar, x: x, y: y, top: top, left: left, right: right, bottom: bottom, width: width, height: height };
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    DockLayout.prototype.init = function () {
	        var _this = this;
	        // Perform superclass initialization.
	        _super.prototype.init.call(this);
	        // Attach each widget to the parent.
	        algorithm_1.each(this, function (widget) { _this.attachWidget(widget); });
	        // Attach each handle to the parent.
	        algorithm_1.each(this.handles(), function (handle) { _this.parent.node.appendChild(handle); });
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Attach the widget to the layout parent widget.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a no-op if the widget is already attached.
	     */
	    DockLayout.prototype.attachWidget = function (widget) {
	        // Do nothing if the widget is already attached.
	        if (this.parent.node === widget.node.parentNode) {
	            return;
	        }
	        // Create the layout item for the widget.
	        this._items.set(widget, new layout_1.LayoutItem(widget));
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	    };
	    /**
	     * Detach the widget from the layout parent widget.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a no-op if the widget is not attached.
	     */
	    DockLayout.prototype.detachWidget = function (widget) {
	        // Do nothing if the widget is not attached.
	        if (this.parent.node !== widget.node.parentNode) {
	            return;
	        }
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Delete the layout item for the widget.
	        var item = this._items.get(widget);
	        if (item) {
	            this._items.delete(widget);
	            item.dispose();
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    DockLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    DockLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    DockLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    DockLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    DockLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    DockLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    DockLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Remove the specified widget from the layout structure.
	     *
	     * #### Notes
	     * This is a no-op if the widget is not in the layout tree.
	     *
	     * This does not detach the widget from the parent node.
	     */
	    DockLayout.prototype._removeWidget = function (widget) {
	        // Bail early if there is no layout root.
	        if (!this._root) {
	            return;
	        }
	        // Find the tab node which contains the given widget.
	        var tabNode = this._root.findTabNode(widget);
	        // Bail early if the tab node is not found.
	        if (!tabNode) {
	            return;
	        }
	        // If there are multiple tabs, just remove the widget's tab.
	        if (tabNode.tabBar.titles.length > 1) {
	            tabNode.tabBar.removeTab(widget.title);
	            return;
	        }
	        // Otherwise, the tab node needs to be removed...
	        // Dispose the tab bar.
	        tabNode.tabBar.dispose();
	        // Handle the case where the tab node is the root.
	        if (this._root === tabNode) {
	            this._root = null;
	            return;
	        }
	        // Otherwise, remove the tab node from its parent...
	        // Prevent widget resizing unless needed.
	        this._root.holdAllSizes();
	        // Clear the parent reference on the tab node.
	        var splitNode = tabNode.parent;
	        tabNode.parent = null;
	        // Remove the tab node from its parent split node.
	        var i = algorithm_1.ArrayExt.removeFirstOf(splitNode.children, tabNode);
	        var handle = algorithm_1.ArrayExt.removeAt(splitNode.handles, i);
	        algorithm_1.ArrayExt.removeAt(splitNode.sizers, i);
	        // Remove the handle from its parent DOM node.
	        if (handle.parentNode) {
	            handle.parentNode.removeChild(handle);
	        }
	        // If there are multiple children, just update the handles.
	        if (splitNode.children.length > 1) {
	            splitNode.syncHandles();
	            return;
	        }
	        // Otherwise, the split node also needs to be removed...
	        // Clear the parent reference on the split node.
	        var maybeParent = splitNode.parent;
	        splitNode.parent = null;
	        // Lookup the remaining child node and handle.
	        var childNode = splitNode.children[0];
	        var childHandle = splitNode.handles[0];
	        // Clear the split node data.
	        splitNode.children.length = 0;
	        splitNode.handles.length = 0;
	        splitNode.sizers.length = 0;
	        // Remove the child handle from its parent node.
	        if (childHandle.parentNode) {
	            childHandle.parentNode.removeChild(childHandle);
	        }
	        // Handle the case where the split node is the root.
	        if (this._root === splitNode) {
	            childNode.parent = null;
	            this._root = childNode;
	            return;
	        }
	        // Otherwise, move the child node to the parent node...
	        var parentNode = maybeParent;
	        // Lookup the index of the split node.
	        var j = parentNode.children.indexOf(splitNode);
	        // Handle the case where the child node is a tab node.
	        if (childNode instanceof Private.TabLayoutNode) {
	            childNode.parent = parentNode;
	            parentNode.children[j] = childNode;
	            return;
	        }
	        // Remove the split data from the parent.
	        var splitHandle = algorithm_1.ArrayExt.removeAt(parentNode.handles, j);
	        algorithm_1.ArrayExt.removeAt(parentNode.children, j);
	        algorithm_1.ArrayExt.removeAt(parentNode.sizers, j);
	        // Remove the handle from its parent node.
	        if (splitHandle.parentNode) {
	            splitHandle.parentNode.removeChild(splitHandle);
	        }
	        // The child node and the split parent node will have the same
	        // orientation. Merge the grand-children with the parent node.
	        for (var i_1 = 0, n = childNode.children.length; i_1 < n; ++i_1) {
	            var gChild = childNode.children[i_1];
	            var gHandle = childNode.handles[i_1];
	            var gSizer = childNode.sizers[i_1];
	            algorithm_1.ArrayExt.insert(parentNode.children, j + i_1, gChild);
	            algorithm_1.ArrayExt.insert(parentNode.handles, j + i_1, gHandle);
	            algorithm_1.ArrayExt.insert(parentNode.sizers, j + i_1, gSizer);
	            gChild.parent = parentNode;
	        }
	        // Clear the child node.
	        childNode.children.length = 0;
	        childNode.handles.length = 0;
	        childNode.sizers.length = 0;
	        childNode.parent = null;
	        // Sync the handles on the parent node.
	        parentNode.syncHandles();
	    };
	    /**
	     * Insert a widget next to an existing tab.
	     *
	     * #### Notes
	     * This does not attach the widget to the parent widget.
	     */
	    DockLayout.prototype._insertTab = function (widget, ref, refNode, after) {
	        // Do nothing if the tab is inserted next to itself.
	        if (widget === ref) {
	            return;
	        }
	        // Create the root if it does not exist.
	        if (!this._root) {
	            var tabNode = new Private.TabLayoutNode(this._createTabBar());
	            tabNode.tabBar.addTab(widget.title);
	            this._root = tabNode;
	            return;
	        }
	        // Use the first tab node as the ref node if needed.
	        if (!refNode) {
	            refNode = this._root.findFirstTabNode();
	        }
	        // If the widget is not contained in the ref node, ensure it is
	        // removed from the layout and hidden before being added again.
	        if (refNode.tabBar.titles.indexOf(widget.title) === -1) {
	            this._removeWidget(widget);
	            widget.hide();
	        }
	        // Lookup the target index for inserting the tab.
	        var index;
	        if (ref) {
	            index = refNode.tabBar.titles.indexOf(ref.title);
	        }
	        else {
	            index = refNode.tabBar.currentIndex;
	        }
	        // Insert the widget's tab relative to the target index.
	        refNode.tabBar.insertTab(index + (after ? 1 : 0), widget.title);
	    };
	    /**
	     * Insert a widget as a new split area.
	     *
	     * #### Notes
	     * This does not attach the widget to the parent widget.
	     */
	    DockLayout.prototype._insertSplit = function (widget, ref, refNode, orientation, after) {
	        // Do nothing if there is no effective split.
	        if (widget === ref && refNode && refNode.tabBar.titles.length === 1) {
	            return;
	        }
	        // Ensure the widget is removed from the current layout.
	        this._removeWidget(widget);
	        // Create the tab layout node to hold the widget.
	        var tabNode = new Private.TabLayoutNode(this._createTabBar());
	        tabNode.tabBar.addTab(widget.title);
	        // Set the root if it does not exist.
	        if (!this._root) {
	            this._root = tabNode;
	            return;
	        }
	        // If the ref node parent is null, split the root.
	        if (!refNode || !refNode.parent) {
	            // Ensure the root is split with the correct orientation.
	            var root = this._splitRoot(orientation);
	            // Determine the insert index for the new tab node.
	            var i_2 = after ? root.children.length : 0;
	            // Normalize the split node.
	            root.normalizeSizes();
	            // Create the sizer for new tab node.
	            var sizer = Private.createSizer(refNode ? 1 : Private.GOLDEN_RATIO);
	            // Insert the tab node sized to the golden ratio.
	            algorithm_1.ArrayExt.insert(root.children, i_2, tabNode);
	            algorithm_1.ArrayExt.insert(root.sizers, i_2, sizer);
	            algorithm_1.ArrayExt.insert(root.handles, i_2, this._createHandle());
	            tabNode.parent = root;
	            // Re-normalize the split node to maintain the ratios.
	            root.normalizeSizes();
	            // Finally, synchronize the visibility of the handles.
	            root.syncHandles();
	            return;
	        }
	        // Lookup the split node for the ref widget.
	        var splitNode = refNode.parent;
	        // If the split node already had the correct orientation,
	        // the widget can be inserted into the split node directly.
	        if (splitNode.orientation === orientation) {
	            // Find the index of the ref node.
	            var i_3 = splitNode.children.indexOf(refNode);
	            // Normalize the split node.
	            splitNode.normalizeSizes();
	            // Consume half the space for the insert location.
	            var s = splitNode.sizers[i_3].sizeHint /= 2;
	            // Insert the tab node sized to the other half.
	            var j_1 = i_3 + (after ? 1 : 0);
	            algorithm_1.ArrayExt.insert(splitNode.children, j_1, tabNode);
	            algorithm_1.ArrayExt.insert(splitNode.sizers, j_1, Private.createSizer(s));
	            algorithm_1.ArrayExt.insert(splitNode.handles, j_1, this._createHandle());
	            tabNode.parent = splitNode;
	            // Finally, synchronize the visibility of the handles.
	            splitNode.syncHandles();
	            return;
	        }
	        // Remove the ref node from the split node.
	        var i = algorithm_1.ArrayExt.removeFirstOf(splitNode.children, refNode);
	        // Create a new normalized split node for the children.
	        var childNode = new Private.SplitLayoutNode(orientation);
	        childNode.normalized = true;
	        // Add the ref node sized to half the space.
	        childNode.children.push(refNode);
	        childNode.sizers.push(Private.createSizer(0.5));
	        childNode.handles.push(this._createHandle());
	        refNode.parent = childNode;
	        // Add the tab node sized to the other half.
	        var j = after ? 1 : 0;
	        algorithm_1.ArrayExt.insert(childNode.children, j, tabNode);
	        algorithm_1.ArrayExt.insert(childNode.sizers, j, Private.createSizer(0.5));
	        algorithm_1.ArrayExt.insert(childNode.handles, j, this._createHandle());
	        tabNode.parent = childNode;
	        // Synchronize the visibility of the handles.
	        childNode.syncHandles();
	        // Finally, add the new child node to the original split node.
	        algorithm_1.ArrayExt.insert(splitNode.children, i, childNode);
	        childNode.parent = splitNode;
	    };
	    /**
	     * Ensure the root is a split node with the given orientation.
	     */
	    DockLayout.prototype._splitRoot = function (orientation) {
	        // Bail early if the root already meets the requirements.
	        var oldRoot = this._root;
	        if (oldRoot instanceof Private.SplitLayoutNode) {
	            if (oldRoot.orientation === orientation) {
	                return oldRoot;
	            }
	        }
	        // Create a new root node with the specified orientation.
	        var newRoot = this._root = new Private.SplitLayoutNode(orientation);
	        // Add the old root to the new root.
	        if (oldRoot) {
	            newRoot.children.push(oldRoot);
	            newRoot.sizers.push(Private.createSizer(0));
	            newRoot.handles.push(this._createHandle());
	            oldRoot.parent = newRoot;
	        }
	        // Return the new root as a convenience.
	        return newRoot;
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    DockLayout.prototype._fit = function () {
	        // Set up the computed minimum size.
	        var minW = 0;
	        var minH = 0;
	        // Update the size limits for the layout tree.
	        if (this._root) {
	            var limits = this._root.fit(this._spacing, this._items);
	            minW = limits.minWidth;
	            minH = limits.minHeight;
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    DockLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Bail early if there is no root layout node.
	        if (!this._root) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the actual layout bounds adjusted for border and padding.
	        var x = this._box.paddingTop;
	        var y = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Update the geometry of the layout tree.
	        this._root.update(x, y, width, height, this._spacing, this._items);
	    };
	    /**
	     * Create a new tab bar for use by the dock layout.
	     *
	     * #### Notes
	     * The tab bar will be attached to the parent if it exists.
	     */
	    DockLayout.prototype._createTabBar = function () {
	        // Create the tab bar using the renderer.
	        var tabBar = this.renderer.createTabBar();
	        // Enforce necessary tab bar behavior.
	        tabBar.orientation = 'horizontal';
	        // Reparent and attach the tab bar to the parent if possible.
	        if (this.parent) {
	            tabBar.parent = this.parent;
	            this.attachWidget(tabBar);
	        }
	        // Return the initialized tab bar.
	        return tabBar;
	    };
	    /**
	     * Create a new handle for the dock layout.
	     *
	     * #### Notes
	     * The handle will be attached to the parent if it exists.
	     */
	    DockLayout.prototype._createHandle = function () {
	        // Create the handle using the renderer.
	        var handle = this.renderer.createHandle();
	        // Initialize the handle layout behavior.
	        var style = handle.style;
	        style.position = 'absolute';
	        style.top = '0';
	        style.left = '0';
	        style.width = '0';
	        style.height = '0';
	        // Attach the handle to the parent if it exists.
	        if (this.parent) {
	            this.parent.node.appendChild(handle);
	        }
	        // Return the initialized handle.
	        return handle;
	    };
	    return DockLayout;
	}(layout_1.Layout));
	exports.DockLayout = DockLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A fraction used for sizing root panels; ~= `1 / golden_ratio`.
	     */
	    Private.GOLDEN_RATIO = 0.618;
	    /**
	     * Clamp a spacing value to an integer >= 0.
	     */
	    function clampSpacing(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampSpacing = clampSpacing;
	    /**
	     * Create a box sizer with an initial size hint.
	     */
	    function createSizer(hint) {
	        var sizer = new boxengine_1.BoxSizer();
	        sizer.sizeHint = hint;
	        sizer.size = hint;
	        return sizer;
	    }
	    Private.createSizer = createSizer;
	    /**
	     * Normalize an area config object and collect the visited widgets.
	     */
	    function normalizeAreaConfig(config, widgetSet) {
	        var result;
	        if (config.type === 'tab-area') {
	            result = normalizeTabAreaConfig(config, widgetSet);
	        }
	        else {
	            result = normalizeSplitAreaConfig(config, widgetSet);
	        }
	        return result;
	    }
	    Private.normalizeAreaConfig = normalizeAreaConfig;
	    /**
	     * Convert a normalized area config into a layout tree.
	     */
	    function realizeAreaConfig(config, renderer) {
	        var node;
	        if (config.type === 'tab-area') {
	            node = realizeTabAreaConfig(config, renderer);
	        }
	        else {
	            node = realizeSplitAreaConfig(config, renderer);
	        }
	        return node;
	    }
	    Private.realizeAreaConfig = realizeAreaConfig;
	    /**
	     * A layout node which holds the data for a tabbed area.
	     */
	    var TabLayoutNode = (function () {
	        /**
	         * Construct a new tab layout node.
	         *
	         * @param tabBar - The tab bar to use for the layout node.
	         */
	        function TabLayoutNode(tabBar) {
	            /**
	             * The parent of the layout node.
	             */
	            this.parent = null;
	            this._top = 0;
	            this._left = 0;
	            this._width = 0;
	            this._height = 0;
	            var tabSizer = new boxengine_1.BoxSizer();
	            var widgetSizer = new boxengine_1.BoxSizer();
	            tabSizer.stretch = 0;
	            widgetSizer.stretch = 1;
	            this.tabBar = tabBar;
	            this.sizers = [tabSizer, widgetSizer];
	        }
	        Object.defineProperty(TabLayoutNode.prototype, "top", {
	            /**
	             * The most recent value for the `top` edge of the layout box.
	             */
	            get: function () {
	                return this._top;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(TabLayoutNode.prototype, "left", {
	            /**
	             * The most recent value for the `left` edge of the layout box.
	             */
	            get: function () {
	                return this._left;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(TabLayoutNode.prototype, "width", {
	            /**
	             * The most recent value for the `width` of the layout box.
	             */
	            get: function () {
	                return this._width;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(TabLayoutNode.prototype, "height", {
	            /**
	             * The most recent value for the `height` of the layout box.
	             */
	            get: function () {
	                return this._height;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        /**
	         * Create an iterator for all widgets in the layout tree.
	         */
	        TabLayoutNode.prototype.iterAllWidgets = function () {
	            return algorithm_1.chain(algorithm_1.once(this.tabBar), this.iterUserWidgets());
	        };
	        /**
	         * Create an iterator for the user widgets in the layout tree.
	         */
	        TabLayoutNode.prototype.iterUserWidgets = function () {
	            return algorithm_1.map(this.tabBar.titles, function (title) { return title.owner; });
	        };
	        /**
	         * Create an iterator for the selected widgets in the layout tree.
	         */
	        TabLayoutNode.prototype.iterSelectedWidgets = function () {
	            var title = this.tabBar.currentTitle;
	            return title ? algorithm_1.once(title.owner) : algorithm_1.empty();
	        };
	        /**
	         * Create an iterator for the tab bars in the layout tree.
	         */
	        TabLayoutNode.prototype.iterTabBars = function () {
	            return algorithm_1.once(this.tabBar);
	        };
	        /**
	         * Create an iterator for the handles in the layout tree.
	         */
	        TabLayoutNode.prototype.iterHandles = function () {
	            return algorithm_1.empty();
	        };
	        /**
	         * Find the tab layout node which contains the given widget.
	         */
	        TabLayoutNode.prototype.findTabNode = function (widget) {
	            return this.tabBar.titles.indexOf(widget.title) !== -1 ? this : null;
	        };
	        /**
	         * Find the split layout node which contains the given handle.
	         */
	        TabLayoutNode.prototype.findSplitNode = function (handle) {
	            return null;
	        };
	        /**
	         * Find the first tab layout node in a layout tree.
	         */
	        TabLayoutNode.prototype.findFirstTabNode = function () {
	            return this;
	        };
	        /**
	         * Find the tab layout node which contains the local point.
	         */
	        TabLayoutNode.prototype.hitTestTabNodes = function (x, y) {
	            if (x < this._left || x >= this._left + this._width) {
	                return null;
	            }
	            if (y < this._top || y >= this._top + this._height) {
	                return null;
	            }
	            return this;
	        };
	        /**
	         * Create a configuration object for the layout tree.
	         */
	        TabLayoutNode.prototype.createConfig = function () {
	            var widgets = this.tabBar.titles.map(function (title) { return title.owner; });
	            var currentIndex = this.tabBar.currentIndex;
	            return { type: 'tab-area', widgets: widgets, currentIndex: currentIndex };
	        };
	        /**
	         * Recursively hold all of the sizes in the layout tree.
	         *
	         * This ignores the sizers of tab layout nodes.
	         */
	        TabLayoutNode.prototype.holdAllSizes = function () {
	            return;
	        };
	        /**
	         * Fit the layout tree.
	         */
	        TabLayoutNode.prototype.fit = function (spacing, items) {
	            // Set up the limit variables.
	            var minWidth = 0;
	            var minHeight = 0;
	            var maxWidth = Infinity;
	            var maxHeight = Infinity;
	            // Lookup the tab bar layout item.
	            var tabBarItem = items.get(this.tabBar);
	            // Lookup the widget layout item.
	            var current = this.tabBar.currentTitle;
	            var widgetItem = current ? items.get(current.owner) : undefined;
	            // Lookup the tab bar and widget sizers.
	            var _a = this.sizers, tabBarSizer = _a[0], widgetSizer = _a[1];
	            // Update the tab bar limits.
	            if (tabBarItem) {
	                tabBarItem.fit();
	            }
	            // Update the widget limits.
	            if (widgetItem) {
	                widgetItem.fit();
	            }
	            // Update the results and sizer for the tab bar.
	            if (tabBarItem && !tabBarItem.isHidden) {
	                minWidth = Math.max(minWidth, tabBarItem.minWidth);
	                minHeight += tabBarItem.minHeight;
	                tabBarSizer.minSize = tabBarItem.minHeight;
	                tabBarSizer.maxSize = tabBarItem.maxHeight;
	            }
	            else {
	                tabBarSizer.minSize = 0;
	                tabBarSizer.maxSize = 0;
	            }
	            // Update the results and sizer for the current widget.
	            if (widgetItem && !widgetItem.isHidden) {
	                minWidth = Math.max(minWidth, widgetItem.minWidth);
	                minHeight += widgetItem.minHeight;
	                widgetSizer.minSize = widgetItem.minHeight;
	                widgetSizer.maxSize = Infinity;
	            }
	            else {
	                widgetSizer.minSize = 0;
	                widgetSizer.maxSize = Infinity;
	            }
	            // Return the computed size limits for the layout node.
	            return { minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight };
	        };
	        /**
	         * Update the layout tree.
	         */
	        TabLayoutNode.prototype.update = function (left, top, width, height, spacing, items) {
	            // Update the layout box values.
	            this._top = top;
	            this._left = left;
	            this._width = width;
	            this._height = height;
	            // Lookup the tab bar layout item.
	            var tabBarItem = items.get(this.tabBar);
	            // Lookup the widget layout item.
	            var current = this.tabBar.currentTitle;
	            var widgetItem = current ? items.get(current.owner) : undefined;
	            // Distribute the layout space to the sizers.
	            boxengine_1.BoxEngine.calc(this.sizers, height);
	            // Update the tab bar item using the computed size.
	            if (tabBarItem && !tabBarItem.isHidden) {
	                var size = this.sizers[0].size;
	                tabBarItem.update(left, top, width, size);
	                top += size;
	            }
	            // Layout the widget using the computed size.
	            if (widgetItem && !widgetItem.isHidden) {
	                var size = this.sizers[1].size;
	                widgetItem.update(left, top, width, size);
	            }
	        };
	        return TabLayoutNode;
	    }());
	    Private.TabLayoutNode = TabLayoutNode;
	    /**
	     * A layout node which holds the data for a split area.
	     */
	    var SplitLayoutNode = (function () {
	        /**
	         * Construct a new split layout node.
	         *
	         * @param orientation - The orientation of the node.
	         */
	        function SplitLayoutNode(orientation) {
	            /**
	             * The parent of the layout node.
	             */
	            this.parent = null;
	            /**
	             * Whether the sizers have been normalized.
	             */
	            this.normalized = false;
	            /**
	             * The child nodes for the split node.
	             */
	            this.children = [];
	            /**
	             * The box sizers for the layout children.
	             */
	            this.sizers = [];
	            /**
	             * The handles for the layout children.
	             */
	            this.handles = [];
	            this.orientation = orientation;
	        }
	        /**
	         * Create an iterator for all widgets in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterAllWidgets = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterAllWidgets(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the user widgets in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterUserWidgets = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterUserWidgets(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the selected widgets in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterSelectedWidgets = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterSelectedWidgets(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the tab bars in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterTabBars = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterTabBars(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the handles in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterHandles = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterHandles(); });
	            return algorithm_1.chain(this.handles, new algorithm_1.ChainIterator(children));
	        };
	        /**
	         * Find the tab layout node which contains the given widget.
	         */
	        SplitLayoutNode.prototype.findTabNode = function (widget) {
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var result = this.children[i].findTabNode(widget);
	                if (result) {
	                    return result;
	                }
	            }
	            return null;
	        };
	        /**
	         * Find the split layout node which contains the given handle.
	         */
	        SplitLayoutNode.prototype.findSplitNode = function (handle) {
	            var index = this.handles.indexOf(handle);
	            if (index !== -1) {
	                return { index: index, node: this };
	            }
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var result = this.children[i].findSplitNode(handle);
	                if (result) {
	                    return result;
	                }
	            }
	            return null;
	        };
	        /**
	         * Find the first tab layout node in a layout tree.
	         */
	        SplitLayoutNode.prototype.findFirstTabNode = function () {
	            if (this.children.length === 0) {
	                return null;
	            }
	            return this.children[0].findFirstTabNode();
	        };
	        /**
	         * Find the tab layout node which contains the local point.
	         */
	        SplitLayoutNode.prototype.hitTestTabNodes = function (x, y) {
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var result = this.children[i].hitTestTabNodes(x, y);
	                if (result) {
	                    return result;
	                }
	            }
	            return null;
	        };
	        /**
	         * Create a configuration object for the layout tree.
	         */
	        SplitLayoutNode.prototype.createConfig = function () {
	            var orientation = this.orientation;
	            var sizes = this.createNormalizedSizes();
	            var children = this.children.map(function (child) { return child.createConfig(); });
	            return { type: 'split-area', orientation: orientation, children: children, sizes: sizes };
	        };
	        /**
	         * Sync the visibility and orientation of the handles.
	         */
	        SplitLayoutNode.prototype.syncHandles = function () {
	            var _this = this;
	            algorithm_1.each(this.handles, function (handle, i) {
	                handle.setAttribute('data-orientation', _this.orientation);
	                if (i === _this.handles.length - 1) {
	                    handle.classList.add('p-mod-hidden');
	                }
	                else {
	                    handle.classList.remove('p-mod-hidden');
	                }
	            });
	        };
	        /**
	         * Hold the current sizes of the box sizers.
	         *
	         * This sets the size hint of each sizer to its current size.
	         */
	        SplitLayoutNode.prototype.holdSizes = function () {
	            algorithm_1.each(this.sizers, function (sizer) { sizer.sizeHint = sizer.size; });
	        };
	        /**
	         * Recursively hold all of the sizes in the layout tree.
	         *
	         * This ignores the sizers of tab layout nodes.
	         */
	        SplitLayoutNode.prototype.holdAllSizes = function () {
	            algorithm_1.each(this.children, function (child) { return child.holdAllSizes(); });
	            this.holdSizes();
	        };
	        /**
	         * Normalize the sizes of the split layout node.
	         */
	        SplitLayoutNode.prototype.normalizeSizes = function () {
	            // Bail early if the sizers are empty.
	            var n = this.sizers.length;
	            if (n === 0) {
	                return;
	            }
	            // Hold the current sizes of the sizers.
	            this.holdSizes();
	            // Compute the sum of the sizes.
	            var sum = algorithm_1.reduce(this.sizers, function (v, sizer) { return v + sizer.sizeHint; }, 0);
	            // Normalize the sizes based on the sum.
	            if (sum === 0) {
	                algorithm_1.each(this.sizers, function (sizer) {
	                    sizer.size = sizer.sizeHint = 1 / n;
	                });
	            }
	            else {
	                algorithm_1.each(this.sizers, function (sizer) {
	                    sizer.size = sizer.sizeHint /= sum;
	                });
	            }
	            // Mark the sizes as normalized.
	            this.normalized = true;
	        };
	        /**
	         * Snap the normalized sizes of the split layout node.
	         */
	        SplitLayoutNode.prototype.createNormalizedSizes = function () {
	            // Bail early if the sizers are empty.
	            var n = this.sizers.length;
	            if (n === 0) {
	                return [];
	            }
	            // Grab the current sizes of the sizers.
	            var sizes = this.sizers.map(function (sizer) { return sizer.size; });
	            // Compute the sum of the sizes.
	            var sum = algorithm_1.reduce(sizes, function (v, size) { return v + size; }, 0);
	            // Normalize the sizes based on the sum.
	            if (sum === 0) {
	                algorithm_1.each(sizes, function (size, i) { sizes[i] = 1 / n; });
	            }
	            else {
	                algorithm_1.each(sizes, function (size, i) { sizes[i] = size / sum; });
	            }
	            // Return the normalized sizes.
	            return sizes;
	        };
	        /**
	         * Fit the layout tree.
	         */
	        SplitLayoutNode.prototype.fit = function (spacing, items) {
	            // Compute the required fixed space.
	            var horizontal = this.orientation === 'horizontal';
	            var fixed = Math.max(0, this.children.length - 1) * spacing;
	            // Set up the limit variables.
	            var minWidth = horizontal ? fixed : 0;
	            var minHeight = horizontal ? 0 : fixed;
	            var maxWidth = Infinity;
	            var maxHeight = Infinity;
	            // Fit the children and update the limits.
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var limits = this.children[i].fit(spacing, items);
	                if (horizontal) {
	                    minHeight = Math.max(minHeight, limits.minHeight);
	                    minWidth += limits.minWidth;
	                    this.sizers[i].minSize = limits.minWidth;
	                }
	                else {
	                    minWidth = Math.max(minWidth, limits.minWidth);
	                    minHeight += limits.minHeight;
	                    this.sizers[i].minSize = limits.minHeight;
	                }
	            }
	            // Return the computed limits for the layout node.
	            return { minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight };
	        };
	        /**
	         * Update the layout tree.
	         */
	        SplitLayoutNode.prototype.update = function (left, top, width, height, spacing, items) {
	            // Compute the available layout space.
	            var horizontal = this.orientation === 'horizontal';
	            var fixed = Math.max(0, this.children.length - 1) * spacing;
	            var space = Math.max(0, (horizontal ? width : height) - fixed);
	            // De-normalize the sizes if needed.
	            if (this.normalized) {
	                algorithm_1.each(this.sizers, function (sizer) { sizer.sizeHint *= space; });
	                this.normalized = false;
	            }
	            // Distribute the layout space to the sizers.
	            boxengine_1.BoxEngine.calc(this.sizers, space);
	            // Update the geometry of the child nodes and handles.
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var child = this.children[i];
	                var size = this.sizers[i].size;
	                var handleStyle = this.handles[i].style;
	                if (horizontal) {
	                    child.update(left, top, size, height, spacing, items);
	                    left += size;
	                    handleStyle.top = top + "px";
	                    handleStyle.left = left + "px";
	                    handleStyle.width = spacing + "px";
	                    handleStyle.height = height + "px";
	                    left += spacing;
	                }
	                else {
	                    child.update(left, top, width, size, spacing, items);
	                    top += size;
	                    handleStyle.top = top + "px";
	                    handleStyle.left = left + "px";
	                    handleStyle.width = width + "px";
	                    handleStyle.height = spacing + "px";
	                    top += spacing;
	                }
	            }
	        };
	        return SplitLayoutNode;
	    }());
	    Private.SplitLayoutNode = SplitLayoutNode;
	    /**
	     * Normalize a tab area config and collect the visited widgets.
	     */
	    function normalizeTabAreaConfig(config, widgetSet) {
	        // Bail early if there is no content.
	        if (config.widgets.length === 0) {
	            return null;
	        }
	        // Setup the filtered widgets array.
	        var widgets = [];
	        // Filter the config for unique widgets.
	        algorithm_1.each(config.widgets, function (widget) {
	            if (!widgetSet.has(widget)) {
	                widgetSet.add(widget);
	                widgets.push(widget);
	            }
	        });
	        // Bail if there are no effective widgets.
	        if (widgets.length === 0) {
	            return null;
	        }
	        // Normalize the current index.
	        var index = config.currentIndex;
	        if (index !== -1 && (index < 0 || index >= widgets.length)) {
	            index = 0;
	        }
	        // Return a normalized config object.
	        return { type: 'tab-area', widgets: widgets, currentIndex: index };
	    }
	    /**
	     * Normalize a split area config and collect the visited widgets.
	     */
	    function normalizeSplitAreaConfig(config, widgetSet) {
	        // Set up the result variables.
	        var orientation = config.orientation;
	        var children = [];
	        var sizes = [];
	        // Normalize the config children.
	        for (var i = 0, n = config.children.length; i < n; ++i) {
	            // Normalize the child config.
	            var child = normalizeAreaConfig(config.children[i], widgetSet);
	            // Ignore an empty child.
	            if (!child) {
	                continue;
	            }
	            // Add the child or hoist its content as appropriate.
	            if (child.type === 'tab-area' || child.orientation !== orientation) {
	                children.push(child);
	                sizes.push(Math.abs(config.sizes[i] || 0));
	            }
	            else {
	                children.push.apply(children, child.children);
	                sizes.push.apply(sizes, child.sizes);
	            }
	        }
	        // Bail if there are no effective children.
	        if (children.length === 0) {
	            return null;
	        }
	        // If there is only one effective child, return that child.
	        if (children.length === 1) {
	            return children[0];
	        }
	        // Return a normalized config object.
	        return { type: 'split-area', orientation: orientation, children: children, sizes: sizes };
	    }
	    /**
	     * Convert a normalized tab area config into a layout tree.
	     */
	    function realizeTabAreaConfig(config, renderer) {
	        // Create the tab bar for the layout node.
	        var tabBar = renderer.createTabBar();
	        // Hide each widget and add it to the tab bar.
	        algorithm_1.each(config.widgets, function (widget) {
	            widget.hide();
	            tabBar.addTab(widget.title);
	        });
	        // Set the current index of the tab bar.
	        tabBar.currentIndex = config.currentIndex;
	        // Return the new tab layout node.
	        return new TabLayoutNode(tabBar);
	    }
	    /**
	     * Convert a normalized split area config into a layout tree.
	     */
	    function realizeSplitAreaConfig(config, renderer) {
	        // Create the split layout node.
	        var node = new SplitLayoutNode(config.orientation);
	        // Add each child to the layout node.
	        algorithm_1.each(config.children, function (child, i) {
	            // Create the child data for the layout node.
	            var childNode = realizeAreaConfig(child, renderer);
	            var sizer = createSizer(config.sizes[i]);
	            var handle = renderer.createHandle();
	            // Add the child data to the layout node.
	            node.children.push(childNode);
	            node.handles.push(handle);
	            node.sizers.push(sizer);
	            // Update the parent for the child node.
	            childNode.parent = node;
	        });
	        // Synchronize the handle state for the layout node.
	        node.syncHandles();
	        // Normalize the sizes for the layout node.
	        node.normalizeSizes();
	        // Return the new layout node.
	        return node;
	    }
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var coreutils_1 = __webpack_require__(6);
	var domutils_1 = __webpack_require__(192);
	var dragdrop_1 = __webpack_require__(216);
	var messaging_1 = __webpack_require__(196);
	var properties_1 = __webpack_require__(199);
	var signaling_1 = __webpack_require__(201);
	var docklayout_1 = __webpack_require__(214);
	var tabbar_1 = __webpack_require__(217);
	var widget_1 = __webpack_require__(202);
	/**
	 * A widget which provides a flexible docking area for widgets.
	 */
	var DockPanel = (function (_super) {
	    __extends(DockPanel, _super);
	    /**
	     * Construct a new dock panel.
	     *
	     * @param options - The options for initializing the panel.
	     */
	    function DockPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._drag = null;
	        _this._pressData = null;
	        _this._layoutModified = new signaling_1.Signal(_this);
	        _this.addClass('p-DockPanel');
	        _this._mode = options.mode || 'multiple-document';
	        _this._renderer = options.renderer || DockPanel.defaultRenderer;
	        // Toggle the CSS mode attribute.
	        _this.dataset['mode'] = _this._mode;
	        // Create the delegate renderer for the layout.
	        var renderer = {
	            createTabBar: function () { return _this._createTabBar(); },
	            createHandle: function () { return _this._createHandle(); }
	        };
	        // Set up the dock layout for the panel.
	        _this.layout = new docklayout_1.DockLayout({ renderer: renderer, spacing: options.spacing });
	        // Set up the overlay drop indicator.
	        _this.overlay = options.overlay || new DockPanel.Overlay();
	        _this.node.appendChild(_this.overlay.node);
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the panel.
	     */
	    DockPanel.prototype.dispose = function () {
	        // Ensure the mouse is released.
	        this._releaseMouse();
	        // Hide the overlay.
	        this.overlay.hide(0);
	        // Cancel a drag if one is in progress.
	        if (this._drag) {
	            this._drag.dispose();
	        }
	        // Dispose of the base class.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(DockPanel.prototype, "layoutModified", {
	        /**
	         * A signal emitted when the layout configuration is modified.
	         *
	         * #### Notes
	         * This signal is emitted whenever the current layout configuration
	         * may have changed.
	         *
	         * This signal is emitted asynchronously in a collapsed fashion, so
	         * that multiple synchronous modifications results in only a single
	         * emit of the signal.
	         */
	        get: function () {
	            return this._layoutModified;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "renderer", {
	        /**
	         * The renderer used by the dock panel.
	         */
	        get: function () {
	            return this.layout.renderer;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "spacing", {
	        /**
	         * Get the spacing between the widgets.
	         */
	        get: function () {
	            return this.layout.spacing;
	        },
	        /**
	         * Set the spacing between the widgets.
	         */
	        set: function (value) {
	            this.layout.spacing = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "mode", {
	        /**
	         * Get the mode for the dock panel.
	         */
	        get: function () {
	            return this._mode;
	        },
	        /**
	         * Set the mode for the dock panel.
	         *
	         * #### Notes
	         * Changing the mode is a destructive operation with respect to the
	         * panel's layout configuration. If layout state must be preserved,
	         * save the current layout config before changing the mode.
	         */
	        set: function (value) {
	            // Bail early if the mode does not change.
	            if (this._mode === value) {
	                return;
	            }
	            // Update the internal mode.
	            this._mode = value;
	            // Toggle the CSS mode attribute.
	            this.dataset['mode'] = value;
	            // Get the layout for the panel.
	            var layout = this.layout;
	            // Configure the layout for the specified mode.
	            switch (value) {
	                case 'multiple-document':
	                    algorithm_1.each(layout.tabBars(), function (tabBar) { tabBar.show(); });
	                    break;
	                case 'single-document':
	                    layout.restoreLayout(Private.createSingleDocumentConfig(this));
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	            // Schedule an emit of the layout modified signal.
	            messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "isEmpty", {
	        /**
	         * Whether the dock panel is empty.
	         */
	        get: function () {
	            return this.layout.isEmpty;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the user widgets in the panel.
	     *
	     * @returns A new iterator over the user widgets in the panel.
	     *
	     * #### Notes
	     * This iterator does not include the generated tab bars.
	     */
	    DockPanel.prototype.widgets = function () {
	        return this.layout.widgets();
	    };
	    /**
	     * Create an iterator over the selected widgets in the panel.
	     *
	     * @returns A new iterator over the selected user widgets.
	     *
	     * #### Notes
	     * This iterator yields the widgets corresponding to the current tab
	     * of each tab bar in the panel.
	     */
	    DockPanel.prototype.selectedWidgets = function () {
	        return this.layout.selectedWidgets();
	    };
	    /**
	     * Create an iterator over the tab bars in the panel.
	     *
	     * @returns A new iterator over the tab bars in the panel.
	     *
	     * #### Notes
	     * This iterator does not include the user widgets.
	     */
	    DockPanel.prototype.tabBars = function () {
	        return this.layout.tabBars();
	    };
	    /**
	     * Create an iterator over the handles in the panel.
	     *
	     * @returns A new iterator over the handles in the panel.
	     */
	    DockPanel.prototype.handles = function () {
	        return this.layout.handles();
	    };
	    /**
	     * Select a specific widget in the dock panel.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * This will make the widget the current widget in its tab area.
	     */
	    DockPanel.prototype.selectWidget = function (widget) {
	        // Find the tab bar which contains the widget.
	        var tabBar = algorithm_1.find(this.tabBars(), function (bar) {
	            return bar.titles.indexOf(widget.title) !== -1;
	        });
	        // Throw an error if no tab bar is found.
	        if (!tabBar) {
	            throw new Error('Widget is not contained in the dock panel.');
	        }
	        // Ensure the widget is the current widget.
	        tabBar.currentTitle = widget.title;
	    };
	    /**
	     * Activate a specified widget in the dock panel.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * This will select and activate the given widget.
	     */
	    DockPanel.prototype.activateWidget = function (widget) {
	        this.selectWidget(widget);
	        widget.activate();
	    };
	    /**
	     * Save the current layout configuration of the dock panel.
	     *
	     * @returns A new config object for the current layout state.
	     *
	     * #### Notes
	     * The return value can be provided to the `restoreLayout` method
	     * in order to restore the layout to its current configuration.
	     */
	    DockPanel.prototype.saveLayout = function () {
	        return this.layout.saveLayout();
	    };
	    /**
	     * Restore the layout to a previously saved configuration.
	     *
	     * @param config - The layout configuration to restore.
	     *
	     * #### Notes
	     * Widgets which currently belong to the layout but which are not
	     * contained in the config will be unparented.
	     *
	     * The dock panel automatically reverts to `'multiple-document'`
	     * mode when a layout config is restored.
	     */
	    DockPanel.prototype.restoreLayout = function (config) {
	        // Reset the mode.
	        this._mode = 'multiple-document';
	        // Restore the layout.
	        this.layout.restoreLayout(config);
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Add a widget to the dock panel.
	     *
	     * @param widget - The widget to add to the dock panel.
	     *
	     * @param options - The additional options for adding the widget.
	     *
	     * #### Notes
	     * If the panel is in single document mode, the options are ignored
	     * and the widget is always added as tab in the hidden tab bar.
	     */
	    DockPanel.prototype.addWidget = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        // Add the widget to the layout.
	        if (this._mode === 'single-document') {
	            this.layout.addWidget(widget);
	        }
	        else {
	            this.layout.addWidget(widget, options);
	        }
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Process a message sent to the widget.
	     *
	     * @param msg - The message sent to the widget.
	     */
	    DockPanel.prototype.processMessage = function (msg) {
	        if (msg.type === 'layout-modified') {
	            this._layoutModified.emit(undefined);
	        }
	        else {
	            _super.prototype.processMessage.call(this, msg);
	        }
	    };
	    /**
	     * Handle the DOM events for the dock panel.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    DockPanel.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'p-dragenter':
	                this._evtDragEnter(event);
	                break;
	            case 'p-dragleave':
	                this._evtDragLeave(event);
	                break;
	            case 'p-dragover':
	                this._evtDragOver(event);
	                break;
	            case 'p-drop':
	                this._evtDrop(event);
	                break;
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    DockPanel.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('p-dragenter', this);
	        this.node.addEventListener('p-dragleave', this);
	        this.node.addEventListener('p-dragover', this);
	        this.node.addEventListener('p-drop', this);
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    DockPanel.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('p-dragenter', this);
	        this.node.removeEventListener('p-dragleave', this);
	        this.node.removeEventListener('p-dragover', this);
	        this.node.removeEventListener('p-drop', this);
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    DockPanel.prototype.onChildAdded = function (msg) {
	        // Ignore the generated tab bars.
	        if (Private.isGeneratedTabBarProperty.get(msg.child)) {
	            return;
	        }
	        // Add the widget class to the child.
	        msg.child.addClass('p-DockPanel-widget');
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    DockPanel.prototype.onChildRemoved = function (msg) {
	        // Ignore the generated tab bars.
	        if (Private.isGeneratedTabBarProperty.get(msg.child)) {
	            return;
	        }
	        // Remove the widget class from the child.
	        msg.child.removeClass('p-DockPanel-widget');
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Handle the `'p-dragenter'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragEnter = function (event) {
	        // If the factory mime type is present, mark the event as
	        // handled in order to get the rest of the drag events.
	        if (event.mimeData.hasData('application/vnd.phosphor.widget-factory')) {
	            event.preventDefault();
	            event.stopPropagation();
	        }
	    };
	    /**
	     * Handle the `'p-dragleave'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragLeave = function (event) {
	        // Mark the event as handled.
	        event.preventDefault();
	        event.stopPropagation();
	        // Get the node into which the drag is entering.
	        var related = event.relatedTarget;
	        // Hide the overlay if the drag is leaving the dock panel.
	        if (!related || !this.node.contains(related)) {
	            this.overlay.hide(0);
	        }
	    };
	    /**
	     * Handle the `'p-dragover'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragOver = function (event) {
	        // Mark the event as handled.
	        event.preventDefault();
	        event.stopPropagation();
	        // Show the drop indicator overlay and update the drop
	        // action based on the drop target zone under the mouse.
	        if (this._showOverlay(event.clientX, event.clientY) === 'invalid') {
	            event.dropAction = 'none';
	        }
	        else {
	            event.dropAction = event.proposedAction;
	        }
	    };
	    /**
	     * Handle the `'p-drop'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDrop = function (event) {
	        // Mark the event as handled.
	        event.preventDefault();
	        event.stopPropagation();
	        // Hide the drop indicator overlay.
	        this.overlay.hide(0);
	        // Bail if the proposed action is to do nothing.
	        if (event.proposedAction === 'none') {
	            event.dropAction = 'none';
	            return;
	        }
	        // Find the drop target under the mouse.
	        var clientX = event.clientX, clientY = event.clientY;
	        var _a = Private.findDropTarget(this, clientX, clientY), zone = _a.zone, target = _a.target;
	        // Bail if the drop zone is invalid.
	        if (zone === 'invalid') {
	            event.dropAction = 'none';
	            return;
	        }
	        // Bail if the factory mime type has invalid data.
	        var mimeData = event.mimeData;
	        var factory = mimeData.getData('application/vnd.phosphor.widget-factory');
	        if (typeof factory !== 'function') {
	            event.dropAction = 'none';
	            return;
	        }
	        // Bail if the factory does not produce a widget.
	        var widget = factory();
	        if (!(widget instanceof widget_1.Widget)) {
	            event.dropAction = 'none';
	            return;
	        }
	        // Bail if the widget is an ancestor of the dock panel.
	        if (widget.contains(this)) {
	            event.dropAction = 'none';
	            return;
	        }
	        // Find the reference widget for the drop target.
	        var ref = target ? Private.getDropRef(target.tabBar) : null;
	        // Add the widget according to the indicated drop zone.
	        switch (zone) {
	            case 'root-all':
	                this.addWidget(widget);
	                break;
	            case 'root-top':
	                this.addWidget(widget, { mode: 'split-top' });
	                break;
	            case 'root-left':
	                this.addWidget(widget, { mode: 'split-left' });
	                break;
	            case 'root-right':
	                this.addWidget(widget, { mode: 'split-right' });
	                break;
	            case 'root-bottom':
	                this.addWidget(widget, { mode: 'split-bottom' });
	                break;
	            case 'widget-all':
	                this.addWidget(widget, { mode: 'tab-after', ref: ref });
	                break;
	            case 'widget-top':
	                this.addWidget(widget, { mode: 'split-top', ref: ref });
	                break;
	            case 'widget-left':
	                this.addWidget(widget, { mode: 'split-left', ref: ref });
	                break;
	            case 'widget-right':
	                this.addWidget(widget, { mode: 'split-right', ref: ref });
	                break;
	            case 'widget-bottom':
	                this.addWidget(widget, { mode: 'split-bottom', ref: ref });
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Accept the proposed drop action.
	        event.dropAction = event.proposedAction;
	        // Activate the dropped widget.
	        this.activateWidget(widget);
	    };
	    /**
	     * Handle the `'keydown'` event for the dock panel.
	     */
	    DockPanel.prototype._evtKeyDown = function (event) {
	        // Stop input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            // Finalize the mouse release.
	            this._releaseMouse();
	            // Schedule an emit of the layout modified signal.
	            messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the dock panel.
	     */
	    DockPanel.prototype._evtMouseDown = function (event) {
	        // Do nothing if the left mouse button is not pressed.
	        if (event.button !== 0) {
	            return;
	        }
	        // Find the handle which contains the mouse target, if any.
	        var layout = this.layout;
	        var target = event.target;
	        var handle = algorithm_1.find(layout.handles(), function (handle) { return handle.contains(target); });
	        if (!handle) {
	            return;
	        }
	        // Stop the event when a handle is pressed.
	        event.preventDefault();
	        event.stopPropagation();
	        // Add the extra document listeners.
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('contextmenu', this, true);
	        // Compute the offset deltas for the handle press.
	        var rect = handle.getBoundingClientRect();
	        var deltaX = event.clientX - rect.left;
	        var deltaY = event.clientY - rect.top;
	        // Override the cursor and store the press data.
	        var style = window.getComputedStyle(handle);
	        var override = dragdrop_1.Drag.overrideCursor(style.cursor);
	        this._pressData = { handle: handle, deltaX: deltaX, deltaY: deltaY, override: override };
	    };
	    /**
	     * Handle the `'mousemove'` event for the dock panel.
	     */
	    DockPanel.prototype._evtMouseMove = function (event) {
	        // Bail early if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Stop the event when dragging a handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Compute the desired offset position for the handle.
	        var rect = this.node.getBoundingClientRect();
	        var xPos = event.clientX - rect.left - this._pressData.deltaX;
	        var yPos = event.clientY - rect.top - this._pressData.deltaY;
	        // Set the handle as close to the desired position as possible.
	        var layout = this.layout;
	        layout.moveHandle(this._pressData.handle, xPos, yPos);
	    };
	    /**
	     * Handle the `'mouseup'` event for the dock panel.
	     */
	    DockPanel.prototype._evtMouseUp = function (event) {
	        // Do nothing if the left mouse button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Stop the event when releasing a handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Finalize the mouse release.
	        this._releaseMouse();
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Release the mouse grab for the dock panel.
	     */
	    DockPanel.prototype._releaseMouse = function () {
	        // Bail early if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Clear the override cursor.
	        this._pressData.override.dispose();
	        this._pressData = null;
	        // Remove the extra document listeners.
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('contextmenu', this, true);
	    };
	    /**
	     * Show the overlay indicator at the given client position.
	     *
	     * Returns the drop zone at the specified client position.
	     *
	     * #### Notes
	     * If the position is not over a valid zone, the overlay is hidden.
	     */
	    DockPanel.prototype._showOverlay = function (clientX, clientY) {
	        // Find the dock target for the given client position.
	        var _a = Private.findDropTarget(this, clientX, clientY), zone = _a.zone, target = _a.target;
	        // If the drop zone is invalid, hide the overlay and bail.
	        if (zone === 'invalid') {
	            this.overlay.hide(100);
	            return zone;
	        }
	        // Setup the variables needed to compute the overlay geometry.
	        var top;
	        var left;
	        var right;
	        var bottom;
	        var box = domutils_1.ElementExt.boxSizing(this.node); // TODO cache this?
	        var rect = this.node.getBoundingClientRect();
	        // Compute the overlay geometry based on the dock zone.
	        switch (zone) {
	            case 'root-all':
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                right = box.paddingRight;
	                bottom = box.paddingBottom;
	                break;
	            case 'root-top':
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                right = box.paddingRight;
	                bottom = rect.height * Private.GOLDEN_RATIO;
	                break;
	            case 'root-left':
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                right = rect.width * Private.GOLDEN_RATIO;
	                bottom = box.paddingBottom;
	                break;
	            case 'root-right':
	                top = box.paddingTop;
	                left = rect.width * Private.GOLDEN_RATIO;
	                right = box.paddingRight;
	                bottom = box.paddingBottom;
	                break;
	            case 'root-bottom':
	                top = rect.height * Private.GOLDEN_RATIO;
	                left = box.paddingLeft;
	                right = box.paddingRight;
	                bottom = box.paddingBottom;
	                break;
	            case 'widget-all':
	                top = target.top;
	                left = target.left;
	                right = target.right;
	                bottom = target.bottom;
	                break;
	            case 'widget-top':
	                top = target.top;
	                left = target.left;
	                right = target.right;
	                bottom = target.bottom + target.height / 2;
	                break;
	            case 'widget-left':
	                top = target.top;
	                left = target.left;
	                right = target.right + target.width / 2;
	                bottom = target.bottom;
	                break;
	            case 'widget-right':
	                top = target.top;
	                left = target.left + target.width / 2;
	                right = target.right;
	                bottom = target.bottom;
	                break;
	            case 'widget-bottom':
	                top = target.top + target.height / 2;
	                left = target.left;
	                right = target.right;
	                bottom = target.bottom;
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Show the overlay with the computed geometry.
	        this.overlay.show({ top: top, left: left, right: right, bottom: bottom });
	        // Finally, return the computed drop zone.
	        return zone;
	    };
	    /**
	     * Create a new tab bar for use by the panel.
	     */
	    DockPanel.prototype._createTabBar = function () {
	        // Create the tab bar.
	        var tabBar = this._renderer.createTabBar();
	        // Set the generated tab bar property for the tab bar.
	        Private.isGeneratedTabBarProperty.set(tabBar, true);
	        // Hide the tab bar when in single document mode.
	        if (this._mode === 'single-document') {
	            tabBar.hide();
	        }
	        // Enforce necessary tab bar behavior.
	        // TODO do we really want to enforce *all* of these?
	        tabBar.tabsMovable = true;
	        tabBar.allowDeselect = false;
	        tabBar.removeBehavior = 'select-previous-tab';
	        tabBar.insertBehavior = 'select-tab-if-needed';
	        // Connect the signal handlers for the tab bar.
	        tabBar.tabMoved.connect(this._onTabMoved, this);
	        tabBar.currentChanged.connect(this._onCurrentChanged, this);
	        tabBar.tabCloseRequested.connect(this._onTabCloseRequested, this);
	        tabBar.tabDetachRequested.connect(this._onTabDetachRequested, this);
	        tabBar.tabActivateRequested.connect(this._onTabActivateRequested, this);
	        // Return the initialized tab bar.
	        return tabBar;
	    };
	    /**
	     * Create a new handle for use by the panel.
	     */
	    DockPanel.prototype._createHandle = function () {
	        return this._renderer.createHandle();
	    };
	    /**
	     * Handle the `tabMoved` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabMoved = function () {
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Handle the `currentChanged` signal from a tab bar.
	     */
	    DockPanel.prototype._onCurrentChanged = function (sender, args) {
	        // Extract the previous and current title from the args.
	        var previousTitle = args.previousTitle, currentTitle = args.currentTitle;
	        // Hide the previous widget.
	        if (previousTitle) {
	            previousTitle.owner.hide();
	        }
	        // Show the current widget.
	        if (currentTitle) {
	            currentTitle.owner.show();
	        }
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Handle the `tabActivateRequested` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabActivateRequested = function (sender, args) {
	        args.title.owner.activate();
	    };
	    /**
	     * Handle the `tabCloseRequested` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabCloseRequested = function (sender, args) {
	        args.title.owner.close();
	    };
	    /**
	     * Handle the `tabDetachRequested` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabDetachRequested = function (sender, args) {
	        var _this = this;
	        // Do nothing if a drag is already in progress.
	        if (this._drag) {
	            return;
	        }
	        // Release the tab bar's hold on the mouse.
	        sender.releaseMouse();
	        // Extract the data from the args.
	        var title = args.title, tab = args.tab, clientX = args.clientX, clientY = args.clientY;
	        // Setup the mime data for the drag operation.
	        var mimeData = new coreutils_1.MimeData();
	        var factory = function () { return title.owner; };
	        mimeData.setData('application/vnd.phosphor.widget-factory', factory);
	        // Create the drag image for the drag operation.
	        var dragImage = tab.cloneNode(true);
	        // Create the drag object to manage the drag-drop operation.
	        this._drag = new dragdrop_1.Drag({
	            mimeData: mimeData, dragImage: dragImage,
	            proposedAction: 'move',
	            supportedActions: 'move',
	        });
	        // Hide the tab node in the original tab.
	        tab.classList.add('p-mod-hidden');
	        // Create the cleanup callback.
	        var cleanup = (function () {
	            _this._drag = null;
	            tab.classList.remove('p-mod-hidden');
	        });
	        // Start the drag operation and cleanup when done.
	        this._drag.start(clientX, clientY).then(cleanup);
	    };
	    return DockPanel;
	}(widget_1.Widget));
	exports.DockPanel = DockPanel;
	/**
	 * The namespace for the `DockPanel` class statics.
	 */
	(function (DockPanel) {
	    /**
	     * A concrete implementation of `IOverlay`.
	     *
	     * This is the default overlay implementation for a dock panel.
	     */
	    var Overlay = (function () {
	        /**
	         * Construct a new overlay.
	         */
	        function Overlay() {
	            this._timer = -1;
	            this._hidden = true;
	            this.node = document.createElement('div');
	            this.node.classList.add('p-DockPanel-overlay');
	            this.node.classList.add('p-mod-hidden');
	            this.node.style.position = 'absolute';
	        }
	        /**
	         * Show the overlay using the given overlay geometry.
	         *
	         * @param geo - The desired geometry for the overlay.
	         */
	        Overlay.prototype.show = function (geo) {
	            // Update the position of the overlay.
	            var style = this.node.style;
	            style.top = geo.top + "px";
	            style.left = geo.left + "px";
	            style.right = geo.right + "px";
	            style.bottom = geo.bottom + "px";
	            // Clear any pending hide timer.
	            clearTimeout(this._timer);
	            this._timer = -1;
	            // If the overlay is already visible, we're done.
	            if (!this._hidden) {
	                return;
	            }
	            // Clear the hidden flag.
	            this._hidden = false;
	            // Finally, show the overlay.
	            this.node.classList.remove('p-mod-hidden');
	        };
	        /**
	         * Hide the overlay node.
	         *
	         * @param delay - The delay (in ms) before hiding the overlay.
	         *   A delay value <= 0 will hide the overlay immediately.
	         */
	        Overlay.prototype.hide = function (delay) {
	            var _this = this;
	            // Do nothing if the overlay is already hidden.
	            if (this._hidden) {
	                return;
	            }
	            // Hide immediately if the delay is <= 0.
	            if (delay <= 0) {
	                clearTimeout(this._timer);
	                this._timer = -1;
	                this._hidden = true;
	                this.node.classList.add('p-mod-hidden');
	                return;
	            }
	            // Do nothing if a hide is already pending.
	            if (this._timer !== -1) {
	                return;
	            }
	            // Otherwise setup the hide timer.
	            this._timer = setTimeout(function () {
	                _this._timer = -1;
	                _this._hidden = true;
	                _this.node.classList.add('p-mod-hidden');
	            }, delay);
	        };
	        return Overlay;
	    }());
	    DockPanel.Overlay = Overlay;
	    /**
	     * The default implementation of `IRenderer`.
	     */
	    var Renderer = (function () {
	        function Renderer() {
	        }
	        /**
	         * Create a new tab bar for use with a dock panel.
	         *
	         * @returns A new tab bar for a dock panel.
	         */
	        Renderer.prototype.createTabBar = function () {
	            var bar = new tabbar_1.TabBar();
	            bar.addClass('p-DockPanel-tabBar');
	            return bar;
	        };
	        /**
	         * Create a new handle node for use with a dock panel.
	         *
	         * @returns A new handle node for a dock panel.
	         */
	        Renderer.prototype.createHandle = function () {
	            var handle = document.createElement('div');
	            handle.className = 'p-DockPanel-handle';
	            return handle;
	        };
	        return Renderer;
	    }());
	    DockPanel.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    DockPanel.defaultRenderer = new Renderer();
	})(DockPanel = exports.DockPanel || (exports.DockPanel = {}));
	exports.DockPanel = DockPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A fraction used for sizing root panels; ~= `1 / golden_ratio`.
	     */
	    Private.GOLDEN_RATIO = 0.618;
	    /**
	     * The size of the edge dock zone for the root panel, in pixels.
	     */
	    Private.EDGE_SIZE = 40;
	    /**
	     * A singleton `'layout-modified'` conflatable message.
	     */
	    Private.LayoutModified = new messaging_1.ConflatableMessage('layout-modified');
	    /**
	     * An attached property used to track generated tab bars.
	     */
	    Private.isGeneratedTabBarProperty = new properties_1.AttachedProperty({
	        name: 'isGeneratedTabBar',
	        create: function () { return false; }
	    });
	    /**
	     * Create a single document config for the widgets in a dock panel.
	     */
	    function createSingleDocumentConfig(panel) {
	        // Return an empty config if the panel is empty.
	        if (panel.isEmpty) {
	            return { main: null };
	        }
	        // Get a flat array of the widgets in the panel.
	        var widgets = algorithm_1.toArray(panel.widgets());
	        // Get the first selected widget in the panel.
	        var selected = panel.selectedWidgets().next();
	        // Compute the current index for the new config.
	        var currentIndex = selected ? widgets.indexOf(selected) : -1;
	        // Return the single document config.
	        return { main: { type: 'tab-area', widgets: widgets, currentIndex: currentIndex } };
	    }
	    Private.createSingleDocumentConfig = createSingleDocumentConfig;
	    /**
	     * Find the drop target at the given client position.
	     */
	    function findDropTarget(panel, clientX, clientY) {
	        // Bail if the mouse is not over the dock panel.
	        if (!domutils_1.ElementExt.hitTest(panel.node, clientX, clientY)) {
	            return { zone: 'invalid', target: null };
	        }
	        // Look up the layout for the panel.
	        var layout = panel.layout;
	        // If the layout is empty, indicate the entire root drop zone.
	        if (layout.isEmpty) {
	            return { zone: 'root-all', target: null };
	        }
	        // Test the edge zones when in multiple document mode.
	        if (panel.mode === 'multiple-document') {
	            // Get the client rect for the dock panel.
	            var panelRect = panel.node.getBoundingClientRect();
	            // Compute the distance to each edge of the panel.
	            var pl = clientX - panelRect.left + 1;
	            var pt = clientY - panelRect.top + 1;
	            var pr = panelRect.right - clientX;
	            var pb = panelRect.bottom - clientY;
	            // Find the minimum distance to an edge.
	            var pd = Math.min(pl, pt, pr, pb);
	            // Return a root zone if the mouse is within an edge.
	            if (pd <= Private.EDGE_SIZE) {
	                var zone_1;
	                switch (pd) {
	                    case pl:
	                        zone_1 = 'root-left';
	                        break;
	                    case pt:
	                        zone_1 = 'root-top';
	                        break;
	                    case pr:
	                        zone_1 = 'root-right';
	                        break;
	                    case pb:
	                        zone_1 = 'root-bottom';
	                        break;
	                    default:
	                        throw 'unreachable';
	                }
	                return { zone: zone_1, target: null };
	            }
	        }
	        // Hit test the dock layout at the given client position.
	        var target = layout.hitTestTabAreas(clientX, clientY);
	        // Bail if no target area was found.
	        if (!target) {
	            return { zone: 'invalid', target: null };
	        }
	        // Return the whole tab area when in single document mode.
	        if (panel.mode === 'single-document') {
	            return { zone: 'widget-all', target: target };
	        }
	        // Compute the distance to each edge of the tab area.
	        var al = target.x - target.left + 1;
	        var at = target.y - target.top + 1;
	        var ar = target.left + target.width - target.x;
	        var ab = target.top + target.height - target.y;
	        // Get the X and Y edge sizes for the area.
	        var rx = Math.round(target.width / 3);
	        var ry = Math.round(target.height / 3);
	        // If the mouse is not within an edge, indicate the entire area.
	        if (al > rx && ar > rx && at > ry && ab > ry) {
	            return { zone: 'widget-all', target: target };
	        }
	        // Scale the distances by the slenderness ratio.
	        al /= rx;
	        at /= ry;
	        ar /= rx;
	        ab /= ry;
	        // Find the minimum distance to the area edge.
	        var ad = Math.min(al, at, ar, ab);
	        // Find the widget zone for the area edge.
	        var zone;
	        switch (ad) {
	            case al:
	                zone = 'widget-left';
	                break;
	            case at:
	                zone = 'widget-top';
	                break;
	            case ar:
	                zone = 'widget-right';
	                break;
	            case ab:
	                zone = 'widget-bottom';
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Return the final drop target.
	        return { zone: zone, target: target };
	    }
	    Private.findDropTarget = findDropTarget;
	    /**
	     * Get the drop reference widget for a tab bar.
	     */
	    function getDropRef(tabBar) {
	        if (tabBar.titles.length === 0) {
	            return null;
	        }
	        if (tabBar.currentTitle) {
	            return tabBar.currentTitle.owner;
	        }
	        return tabBar.titles[tabBar.titles.length - 1].owner;
	    }
	    Private.getDropRef = getDropRef;
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	var disposable_1 = __webpack_require__(209);
	/**
	 * An object which manages a drag-drop operation.
	 *
	 * A drag object dispatches four different events to drop targets:
	 *
	 * - `'p-dragenter'` - Dispatched when the mouse enters the target
	 *   element. This event must be canceled in order to receive any
	 *   of the other events.
	 *
	 * - `'p-dragover'` - Dispatched when the mouse moves over the drop
	 *   target. It must cancel the event and set the `dropAction` to one
	 *   of the supported actions in order to receive drop events.
	 *
	 * - `'p-dragleave'` - Dispatched when the mouse leaves the target
	 *   element. This includes moving the mouse into child elements.
	 *
	 * - `'p-drop'`- Dispatched when the mouse is released over the target
	 *   element when the target indicates an appropriate drop action. If
	 *   the event is canceled, the indicated drop action is returned to
	 *   the initiator through the resolved promise.
	 *
	 * A drag operation can be terminated at any time by pressing `Escape`
	 * or by disposing the drag object.
	 *
	 * A drag object has the ability to automatically scroll a scrollable
	 * element when the mouse is hovered near one of its edges. To enable
	 * this, add the `data-p-dragscroll` attribute to any element which
	 * the drag object should consider for scrolling.
	 *
	 * #### Notes
	 * This class is designed to be used when dragging and dropping custom
	 * data *within* a single application. It is *not* a replacement for
	 * the native drag-drop API. Instead, it provides an API which allows
	 * drag operations to be initiated programmatically and enables the
	 * transfer of arbitrary non-string objects; features which are not
	 * possible with the native drag-drop API.
	 */
	var Drag = (function () {
	    /**
	     * Construct a new drag object.
	     *
	     * @param options - The options for initializing the drag.
	     */
	    function Drag(options) {
	        var _this = this;
	        /**
	         * The scroll loop handler function.
	         */
	        this._onScrollFrame = function () {
	            // Bail early if there is no scroll target.
	            if (!_this._scrollTarget) {
	                return;
	            }
	            // Unpack the scroll target.
	            var _a = _this._scrollTarget, element = _a.element, edge = _a.edge, distance = _a.distance;
	            // Calculate the scroll delta using nonlinear acceleration.
	            var d = Private.SCROLL_EDGE_SIZE - distance;
	            var f = Math.pow(d / Private.SCROLL_EDGE_SIZE, 2);
	            var s = Math.max(1, Math.round(f * Private.SCROLL_EDGE_SIZE));
	            // Scroll the element in the specified direction.
	            switch (edge) {
	                case 'top':
	                    element.scrollTop -= s;
	                    break;
	                case 'left':
	                    element.scrollLeft -= s;
	                    break;
	                case 'right':
	                    element.scrollLeft += s;
	                    break;
	                case 'bottom':
	                    element.scrollTop += s;
	                    break;
	            }
	            // Request the next cycle of the scroll loop.
	            requestAnimationFrame(_this._onScrollFrame);
	        };
	        this._disposed = false;
	        this._dropAction = 'none';
	        this._override = null;
	        this._currentTarget = null;
	        this._currentElement = null;
	        this._promise = null;
	        this._scrollTarget = null;
	        this._resolve = null;
	        this.mimeData = options.mimeData;
	        this.dragImage = options.dragImage || null;
	        this.proposedAction = options.proposedAction || 'copy';
	        this.supportedActions = options.supportedActions || 'all';
	        this.source = options.source || null;
	    }
	    /**
	     * Dispose of the resources held by the drag object.
	     *
	     * #### Notes
	     * This will cancel the drag operation if it is active.
	     */
	    Drag.prototype.dispose = function () {
	        // Do nothing if the drag object is already disposed.
	        if (this._disposed) {
	            return;
	        }
	        this._disposed = true;
	        // If there is a current target, dispatch a drag leave event.
	        if (this._currentTarget) {
	            var event_1 = Private.createMouseEvent('mouseup', -1, -1);
	            Private.dispatchDragLeave(this, this._currentTarget, null, event_1);
	        }
	        // Finalize the drag object with `'none'`.
	        this._finalize('none');
	    };
	    Object.defineProperty(Drag.prototype, "isDisposed", {
	        /**
	         * Test whether the drag object is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Start the drag operation at the specified client position.
	     *
	     * @param clientX - The client X position for the drag start.
	     *
	     * @param clientY - The client Y position for the drag start.
	     *
	     * @returns A promise which resolves to the result of the drag.
	     *
	     * #### Notes
	     * If the drag has already been started, the promise created by the
	     * first call to `start` is returned.
	     *
	     * If the drag operation has ended, or if the drag object has been
	     * disposed, the returned promise will resolve to `'none'`.
	     *
	     * The drag object will be automatically disposed when drag operation
	     * completes. This means `Drag` objects are for single-use only.
	     *
	     * This method assumes the left mouse button is already held down.
	     */
	    Drag.prototype.start = function (clientX, clientY) {
	        var _this = this;
	        // If the drag object is already disposed, resolve to `None`.
	        if (this._disposed) {
	            return Promise.resolve('none');
	        }
	        // If the drag has already been started, return the promise.
	        if (this._promise) {
	            return this._promise;
	        }
	        // Install the document listeners for the drag object.
	        this._addListeners();
	        // Attach the drag image at the specified client position.
	        this._attachDragImage(clientX, clientY);
	        // Create the promise which will be resolved on completion.
	        this._promise = new Promise(function (resolve, reject) {
	            _this._resolve = resolve;
	        });
	        // Trigger a fake move event to kick off the drag operation.
	        var event = Private.createMouseEvent('mousemove', clientX, clientY);
	        document.dispatchEvent(event);
	        // Return the pending promise for the drag operation.
	        return this._promise;
	    };
	    /**
	     * Handle the DOM events for the drag operation.
	     *
	     * @param event - The DOM event sent to the drag object.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the document. It should not be
	     * called directly by user code.
	     */
	    Drag.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            default:
	                // Stop all other events during drag-drop.
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * Handle the `'mousemove'` event for the drag object.
	     */
	    Drag.prototype._evtMouseMove = function (event) {
	        // Stop all input events during drag-drop.
	        event.preventDefault();
	        event.stopPropagation();
	        // Update the current target node and dispatch enter/leave events.
	        this._updateCurrentTarget(event);
	        // Update the drag scroll element.
	        this._updateDragScroll(event);
	        // Move the drag image to the specified client position. This is
	        // performed *after* dispatching to prevent unnecessary reflows.
	        this._moveDragImage(event.clientX, event.clientY);
	    };
	    /**
	     * Handle the `'mouseup'` event for the drag object.
	     */
	    Drag.prototype._evtMouseUp = function (event) {
	        // Stop all input events during drag-drop.
	        event.preventDefault();
	        event.stopPropagation();
	        // Do nothing if the left button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Update the current target node and dispatch enter/leave events.
	        // This prevents a subtle issue where the DOM mutates under the
	        // cursor after the last move event but before the drop event.
	        this._updateCurrentTarget(event);
	        // If there is no current target, finalize with `'none'`.
	        if (!this._currentTarget) {
	            this._finalize('none');
	            return;
	        }
	        // If the last drop action was `'none'`, dispatch a leave event
	        // to the current target and finalize the drag with `'none'`.
	        if (this._dropAction === 'none') {
	            Private.dispatchDragLeave(this, this._currentTarget, null, event);
	            this._finalize('none');
	            return;
	        }
	        // Dispatch the drop event at the current target and finalize
	        // with the resulting drop action.
	        var action = Private.dispatchDrop(this, this._currentTarget, event);
	        this._finalize(action);
	    };
	    /**
	     * Handle the `'keydown'` event for the drag object.
	     */
	    Drag.prototype._evtKeyDown = function (event) {
	        // Stop all input events during drag-drop.
	        event.preventDefault();
	        event.stopPropagation();
	        // Cancel the drag if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            this.dispose();
	        }
	    };
	    /**
	     * Add the document event listeners for the drag object.
	     */
	    Drag.prototype._addListeners = function () {
	        document.addEventListener('mousedown', this, true);
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('mouseenter', this, true);
	        document.addEventListener('mouseleave', this, true);
	        document.addEventListener('mouseover', this, true);
	        document.addEventListener('mouseout', this, true);
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('keyup', this, true);
	        document.addEventListener('keypress', this, true);
	        document.addEventListener('contextmenu', this, true);
	    };
	    /**
	     * Remove the document event listeners for the drag object.
	     */
	    Drag.prototype._removeListeners = function () {
	        document.removeEventListener('mousedown', this, true);
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('mouseenter', this, true);
	        document.removeEventListener('mouseleave', this, true);
	        document.removeEventListener('mouseover', this, true);
	        document.removeEventListener('mouseout', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('keyup', this, true);
	        document.removeEventListener('keypress', this, true);
	        document.removeEventListener('contextmenu', this, true);
	    };
	    /**
	     * Update the drag scroll element under the mouse.
	     */
	    Drag.prototype._updateDragScroll = function (event) {
	        // Find the scroll target under the mouse.
	        var target = Private.findScrollTarget(event);
	        // Bail if there is nothing to scroll.
	        if (!this._scrollTarget && !target) {
	            return;
	        }
	        // Start the scroll loop if needed.
	        if (!this._scrollTarget) {
	            setTimeout(this._onScrollFrame, 500);
	        }
	        // Update the scroll target.
	        this._scrollTarget = target;
	    };
	    /**
	     * Update the current target node using the given mouse event.
	     */
	    Drag.prototype._updateCurrentTarget = function (event) {
	        // Fetch common local state.
	        var prevTarget = this._currentTarget;
	        var currTarget = this._currentTarget;
	        var prevElem = this._currentElement;
	        // Find the current indicated element at the given position.
	        var currElem = document.elementFromPoint(event.clientX, event.clientY);
	        // Update the current element reference.
	        this._currentElement = currElem;
	        // If the indicated element changes from the previous iteration,
	        // and is different from the current target, dispatch the exit
	        // event to the target.
	        if (currElem !== prevElem && currElem !== currTarget) {
	            Private.dispatchDragExit(this, currTarget, currElem, event);
	        }
	        // If the indicated element changes from the previous iteration,
	        // and is different from the current target, dispatch the enter
	        // event and compute the new target element.
	        if (currElem !== prevElem && currElem !== currTarget) {
	            currTarget = Private.dispatchDragEnter(this, currElem, currTarget, event);
	        }
	        // If the current target element has changed, update the current
	        // target reference and dispatch the leave event to the old target.
	        if (currTarget !== prevTarget) {
	            this._currentTarget = currTarget;
	            Private.dispatchDragLeave(this, prevTarget, currTarget, event);
	        }
	        // Dispatch the drag over event and update the drop action.
	        var action = Private.dispatchDragOver(this, currTarget, event);
	        this._setDropAction(action);
	    };
	    /**
	     * Attach the drag image element at the specified location.
	     *
	     * This is a no-op if there is no drag image element.
	     */
	    Drag.prototype._attachDragImage = function (clientX, clientY) {
	        if (!this.dragImage) {
	            return;
	        }
	        this.dragImage.classList.add('p-mod-drag-image');
	        var style = this.dragImage.style;
	        style.pointerEvents = 'none';
	        style.position = 'fixed';
	        style.top = clientY + "px";
	        style.left = clientX + "px";
	        document.body.appendChild(this.dragImage);
	    };
	    /**
	     * Move the drag image element to the specified location.
	     *
	     * This is a no-op if there is no drag image element.
	     */
	    Drag.prototype._moveDragImage = function (clientX, clientY) {
	        if (!this.dragImage) {
	            return;
	        }
	        var style = this.dragImage.style;
	        style.top = clientY + "px";
	        style.left = clientX + "px";
	    };
	    /**
	     * Detach the drag image element from the DOM.
	     *
	     * This is a no-op if there is no drag image element.
	     */
	    Drag.prototype._detachDragImage = function () {
	        if (!this.dragImage) {
	            return;
	        }
	        var parent = this.dragImage.parentNode;
	        if (!parent) {
	            return;
	        }
	        parent.removeChild(this.dragImage);
	    };
	    /**
	     * Set the internal drop action state and update the drag cursor.
	     */
	    Drag.prototype._setDropAction = function (action) {
	        action = Private.validateAction(action, this.supportedActions);
	        if (this._override && this._dropAction === action) {
	            return;
	        }
	        switch (action) {
	            case 'none':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('no-drop');
	                break;
	            case 'copy':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('copy');
	                break;
	            case 'link':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('alias');
	                break;
	            case 'move':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('move');
	                break;
	        }
	    };
	    /**
	     * Finalize the drag operation and resolve the drag promise.
	     */
	    Drag.prototype._finalize = function (action) {
	        // Store the resolve function as a temp variable.
	        var resolve = this._resolve;
	        // Remove the document event listeners.
	        this._removeListeners();
	        // Detach the drag image.
	        this._detachDragImage();
	        // Dispose of the cursor override.
	        if (this._override) {
	            this._override.dispose();
	            this._override = null;
	        }
	        // Clear the mime data.
	        this.mimeData.clear();
	        // Clear the rest of the internal drag state.
	        this._disposed = true;
	        this._dropAction = 'none';
	        this._currentTarget = null;
	        this._currentElement = null;
	        this._scrollTarget = null;
	        this._promise = null;
	        this._resolve = null;
	        // Finally, resolve the promise to the given drop action.
	        if (resolve) {
	            resolve(action);
	        }
	    };
	    return Drag;
	}());
	exports.Drag = Drag;
	/**
	 * The namespace for the `Drag` class statics.
	 */
	(function (Drag) {
	    /**
	     * Override the cursor icon for the entire document.
	     *
	     * @param cursor - The string representing the cursor style.
	     *
	     * @returns A disposable which will clear the override when disposed.
	     *
	     * #### Notes
	     * The most recent call to `overrideCursor` takes precedence.
	     * Disposing an old override has no effect on the current override.
	     *
	     * This utility function is used by the `Drag` class to override the
	     * mouse cursor during a drag-drop operation, but it can also be used
	     * by other classes to fix the cursor icon during normal mouse drags.
	     *
	     * #### Example
	     * ```typescript
	     * import { Drag } from '@phosphor/dragdrop';
	     *
	     * // Force the cursor to be 'wait' for the entire document.
	     * let override = Drag.overrideCursor('wait');
	     *
	     * // Clear the override by disposing the return value.
	     * override.dispose();
	     * ```
	     */
	    function overrideCursor(cursor) {
	        var id = ++overrideCursorID;
	        document.body.style.cursor = cursor;
	        document.body.classList.add('p-mod-override-cursor');
	        return new disposable_1.DisposableDelegate(function () {
	            if (id === overrideCursorID) {
	                document.body.style.cursor = '';
	                document.body.classList.remove('p-mod-override-cursor');
	            }
	        });
	    }
	    Drag.overrideCursor = overrideCursor;
	    /**
	     * The internal id for the active cursor override.
	     */
	    var overrideCursorID = 0;
	})(Drag = exports.Drag || (exports.Drag = {}));
	exports.Drag = Drag;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The size of a drag scroll edge, in pixels.
	     */
	    Private.SCROLL_EDGE_SIZE = 20;
	    /**
	     * Validate the given action is one of the supported actions.
	     *
	     * Returns the given action or `'none'` if the action is unsupported.
	     */
	    function validateAction(action, supported) {
	        return (actionTable[action] & supportedTable[supported]) ? action : 'none';
	    }
	    Private.validateAction = validateAction;
	    /**
	     * Create a left mouse event at the given position.
	     *
	     * @param type - The event type for the mouse event.
	     *
	     * @param clientX - The client X position.
	     *
	     * @param clientY - The client Y position.
	     *
	     * @returns A newly created and initialized mouse event.
	     */
	    function createMouseEvent(type, clientX, clientY) {
	        var event = document.createEvent('MouseEvent');
	        event.initMouseEvent(type, true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
	        return event;
	    }
	    Private.createMouseEvent = createMouseEvent;
	    /**
	     * Find the drag scroll target under the mouse, if any.
	     */
	    function findScrollTarget(event) {
	        // Look up the client mouse position.
	        var x = event.clientX;
	        var y = event.clientY;
	        // Get the element under the mouse.
	        var element = document.elementFromPoint(x, y);
	        // Search for a scrollable target based on the mouse position.
	        // The null assert in third clause of for-loop is required due to:
	        // https://github.com/Microsoft/TypeScript/issues/14143
	        for (; element; element = element.parentElement) {
	            // Ignore elements which are not marked as scrollable.
	            if (!element.hasAttribute('data-p-dragscroll')) {
	                continue;
	            }
	            // Set up the coordinate offsets for the element.
	            var offsetX = 0;
	            var offsetY = 0;
	            if (element === document.body) {
	                offsetX = window.pageXOffset;
	                offsetY = window.pageYOffset;
	            }
	            // Get the element bounds in viewport coordinates.
	            var r = element.getBoundingClientRect();
	            var top_1 = r.top + offsetY;
	            var left = r.left + offsetX;
	            var right = left + r.width;
	            var bottom = top_1 + r.height;
	            // Skip the element if it's not under the mouse.
	            if (x < left || x >= right || y < top_1 || y >= bottom) {
	                continue;
	            }
	            // Compute the distance to each edge.
	            var dl = x - left + 1;
	            var dt = y - top_1 + 1;
	            var dr = right - x;
	            var db = bottom - y;
	            // Find the smallest of the edge distances.
	            var distance = Math.min(dl, dt, dr, db);
	            // Skip the element if the mouse is not within a scroll edge.
	            if (distance > Private.SCROLL_EDGE_SIZE) {
	                continue;
	            }
	            // Set up the edge result variable.
	            var edge = void 0;
	            // Find the edge for the computed distance.
	            switch (distance) {
	                case db:
	                    edge = 'bottom';
	                    break;
	                case dt:
	                    edge = 'top';
	                    break;
	                case dr:
	                    edge = 'right';
	                    break;
	                case dl:
	                    edge = 'left';
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	            // Compute how much the element can scroll in width and height.
	            var dsw = element.scrollWidth - element.clientWidth;
	            var dsh = element.scrollHeight - element.clientHeight;
	            // Determine if the element should be scrolled for the edge.
	            var shouldScroll = void 0;
	            switch (edge) {
	                case 'top':
	                    shouldScroll = dsh > 0 && element.scrollTop > 0;
	                    break;
	                case 'left':
	                    shouldScroll = dsw > 0 && element.scrollLeft > 0;
	                    break;
	                case 'right':
	                    shouldScroll = dsw > 0 && element.scrollLeft < dsw;
	                    break;
	                case 'bottom':
	                    shouldScroll = dsh > 0 && element.scrollTop < dsh;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	            // Skip the element if it should not be scrolled.
	            if (!shouldScroll) {
	                continue;
	            }
	            // Return the drag scroll target.
	            return { element: element, edge: edge, distance: distance };
	        }
	        // No drag scroll target was found.
	        return null;
	    }
	    Private.findScrollTarget = findScrollTarget;
	    /**
	     * Dispatch a drag enter event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param currElem - The currently indicated element, or `null`. This
	     *   is the "immediate user selection" from the whatwg spec.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * @returns The element to use as the current drag target. This is the
	     *   "current target element" from the whatwg spec, and may be `null`.
	     *
	     * #### Notes
	     * This largely implements the drag enter portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragEnter(drag, currElem, currTarget, event) {
	        // If the current element is null, return null as the new target.
	        if (!currElem) {
	            return null;
	        }
	        // Dispatch a drag enter event to the current element.
	        var dragEvent = createDragEvent('p-dragenter', drag, event, currTarget);
	        var canceled = !currElem.dispatchEvent(dragEvent);
	        // If the event was canceled, use the current element as the new target.
	        if (canceled) {
	            return currElem;
	        }
	        // If the current element is the document body, keep the original target.
	        if (currElem === document.body) {
	            return currTarget;
	        }
	        // Dispatch a drag enter event on the document body.
	        dragEvent = createDragEvent('p-dragenter', drag, event, currTarget);
	        document.body.dispatchEvent(dragEvent);
	        // Ignore the event cancellation, and use the body as the new target.
	        return document.body;
	    }
	    Private.dispatchDragEnter = dispatchDragEnter;
	    /**
	     * Dispatch a drag exit event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param prevTarget - The previous target element, or `null`. This
	     *   is the previous "current target element" from the whatwg spec.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * #### Notes
	     * This largely implements the drag exit portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragExit(drag, prevTarget, currTarget, event) {
	        // If the previous target is null, do nothing.
	        if (!prevTarget) {
	            return;
	        }
	        // Dispatch the drag exit event to the previous target.
	        var dragEvent = createDragEvent('p-dragexit', drag, event, currTarget);
	        prevTarget.dispatchEvent(dragEvent);
	    }
	    Private.dispatchDragExit = dispatchDragExit;
	    /**
	     * Dispatch a drag leave event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param prevTarget - The previous target element, or `null`. This
	     *   is the previous "current target element" from the whatwg spec.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * #### Notes
	     * This largely implements the drag leave portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragLeave(drag, prevTarget, currTarget, event) {
	        // If the previous target is null, do nothing.
	        if (!prevTarget) {
	            return;
	        }
	        // Dispatch the drag leave event to the previous target.
	        var dragEvent = createDragEvent('p-dragleave', drag, event, currTarget);
	        prevTarget.dispatchEvent(dragEvent);
	    }
	    Private.dispatchDragLeave = dispatchDragLeave;
	    /**
	     * Dispatch a drag over event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * @returns The `DropAction` result of the drag over event.
	     *
	     * #### Notes
	     * This largely implements the drag over portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragOver(drag, currTarget, event) {
	        // If there is no current target, the drop action is none.
	        if (!currTarget) {
	            return 'none';
	        }
	        // Dispatch the drag over event to the current target.
	        var dragEvent = createDragEvent('p-dragover', drag, event, null);
	        var canceled = !currTarget.dispatchEvent(dragEvent);
	        // If the event was canceled, return the drop action result.
	        if (canceled) {
	            return dragEvent.dropAction;
	        }
	        // Otherwise, the effective drop action is none.
	        return 'none';
	    }
	    Private.dispatchDragOver = dispatchDragOver;
	    /**
	     * Dispatch a drop event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * @returns The `DropAction` result of the drop event.
	     *
	     * #### Notes
	     * This largely implements the drag over portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDrop(drag, currTarget, event) {
	        // If there is no current target, the drop action is none.
	        if (!currTarget) {
	            return 'none';
	        }
	        // Dispatch the drop event to the current target.
	        var dragEvent = createDragEvent('p-drop', drag, event, null);
	        var canceled = !currTarget.dispatchEvent(dragEvent);
	        // If the event was canceled, return the drop action result.
	        if (canceled) {
	            return dragEvent.dropAction;
	        }
	        // Otherwise, the effective drop action is none.
	        return 'none';
	    }
	    Private.dispatchDrop = dispatchDrop;
	    /**
	     * A lookup table from drop action to bit value.
	     */
	    var actionTable = {
	        'none': 0x0,
	        'copy': 0x1,
	        'link': 0x2,
	        'move': 0x4
	    };
	    /**
	     * A lookup table from supported action to drop action bit mask.
	     */
	    var supportedTable = {
	        'none': actionTable['none'],
	        'copy': actionTable['copy'],
	        'link': actionTable['link'],
	        'move': actionTable['move'],
	        'copy-link': actionTable['copy'] | actionTable['link'],
	        'copy-move': actionTable['copy'] | actionTable['move'],
	        'link-move': actionTable['link'] | actionTable['move'],
	        'all': actionTable['copy'] | actionTable['link'] | actionTable['move']
	    };
	    /**
	     * Create a new initialized `IDragEvent` from the given data.
	     *
	     * @param type - The event type for the drag event.
	     *
	     * @param drag - The drag object to use for seeding the drag data.
	     *
	     * @param event - The mouse event to use for seeding the mouse data.
	     *
	     * @param related - The related target for the event, or `null`.
	     *
	     * @returns A new object which implements `IDragEvent`.
	     */
	    function createDragEvent(type, drag, event, related) {
	        // Create a new mouse event to use as the drag event. Currently,
	        // JS engines do now allow user-defined Event subclasses.
	        var dragEvent = document.createEvent('MouseEvent');
	        // Initialize the mouse event data.
	        dragEvent.initMouseEvent(type, true, true, window, 0, event.screenX, event.screenY, event.clientX, event.clientY, event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.button, related);
	        // Forcefully add the custom drag event properties.
	        dragEvent.dropAction = 'none';
	        dragEvent.mimeData = drag.mimeData;
	        dragEvent.proposedAction = drag.proposedAction;
	        dragEvent.supportedActions = drag.supportedActions;
	        dragEvent.source = drag.source;
	        // Return the fully initialized drag event.
	        return dragEvent;
	    }
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var dragdrop_1 = __webpack_require__(216);
	var messaging_1 = __webpack_require__(196);
	var signaling_1 = __webpack_require__(201);
	var virtualdom_1 = __webpack_require__(211);
	var title_1 = __webpack_require__(203);
	var widget_1 = __webpack_require__(202);
	/**
	 * A widget which displays titles as a single row or column of tabs.
	 *
	 * #### Notes
	 * If CSS transforms are used to rotate nodes for vertically oriented
	 * text, then tab dragging will not work correctly. The `tabsMovable`
	 * property should be set to `false` when rotating nodes from CSS.
	 */
	var TabBar = (function (_super) {
	    __extends(TabBar, _super);
	    /**
	     * Construct a new tab bar.
	     *
	     * @param options - The options for initializing the tab bar.
	     */
	    function TabBar(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._currentIndex = -1;
	        _this._titles = [];
	        _this._previousTitle = null;
	        _this._dragData = null;
	        _this._tabMoved = new signaling_1.Signal(_this);
	        _this._currentChanged = new signaling_1.Signal(_this);
	        _this._tabCloseRequested = new signaling_1.Signal(_this);
	        _this._tabDetachRequested = new signaling_1.Signal(_this);
	        _this._tabActivateRequested = new signaling_1.Signal(_this);
	        _this.addClass('p-TabBar');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.tabsMovable = options.tabsMovable || false;
	        _this.allowDeselect = options.allowDeselect || false;
	        _this.insertBehavior = options.insertBehavior || 'select-tab-if-needed';
	        _this.removeBehavior = options.removeBehavior || 'select-tab-after';
	        _this.renderer = options.renderer || TabBar.defaultRenderer;
	        _this._orientation = options.orientation || 'horizontal';
	        _this.dataset['orientation'] = _this._orientation;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    TabBar.prototype.dispose = function () {
	        this._releaseMouse();
	        this._titles.length = 0;
	        this._previousTitle = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(TabBar.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current tab is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected tab is changed
	         * either through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current
	         * tab changes due to tabs being inserted, removed, or moved. It is
	         * only emitted when the actual current tab node is changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabMoved", {
	        /**
	         * A signal emitted when a tab is moved by the user.
	         *
	         * #### Notes
	         * This signal is emitted when a tab is moved by user interaction.
	         *
	         * This signal is not emitted when a tab is moved programmatically.
	         */
	        get: function () {
	            return this._tabMoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabActivateRequested", {
	        /**
	         * A signal emitted when a tab is clicked by the user.
	         *
	         * #### Notes
	         * If the clicked tab is not the current tab, the clicked tab will be
	         * made current and the `currentChanged` signal will be emitted first.
	         *
	         * This signal is emitted even if the clicked tab is the current tab.
	         */
	        get: function () {
	            return this._tabActivateRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabCloseRequested", {
	        /**
	         * A signal emitted when a tab close icon is clicked.
	         *
	         * #### Notes
	         * This signal is not emitted unless the tab title is `closable`.
	         */
	        get: function () {
	            return this._tabCloseRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabDetachRequested", {
	        /**
	         * A signal emitted when a tab is dragged beyond the detach threshold.
	         *
	         * #### Notes
	         * This signal is emitted when the user drags a tab with the mouse,
	         * and mouse is dragged beyond the detach threshold.
	         *
	         * The consumer of the signal should call `releaseMouse` and remove
	         * the tab in order to complete the detach.
	         *
	         * This signal is only emitted once per drag cycle.
	         */
	        get: function () {
	            return this._tabDetachRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "currentTitle", {
	        /**
	         * Get the currently selected title.
	         *
	         * #### Notes
	         * This will be `null` if no tab is selected.
	         */
	        get: function () {
	            return this._titles[this._currentIndex] || null;
	        },
	        /**
	         * Set the currently selected title.
	         *
	         * #### Notes
	         * If the title does not exist, the title will be set to `null`.
	         */
	        set: function (value) {
	            this.currentIndex = value ? this._titles.indexOf(value) : -1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "currentIndex", {
	        /**
	         * Get the index of the currently selected tab.
	         *
	         * #### Notes
	         * This will be `-1` if no tab is selected.
	         */
	        get: function () {
	            return this._currentIndex;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * #### Notes
	         * If the value is out of range, the index will be set to `-1`.
	         */
	        set: function (value) {
	            // Adjust for an out of range index.
	            if (value < 0 || value >= this._titles.length) {
	                value = -1;
	            }
	            // Bail early if the index will not change.
	            if (this._currentIndex === value) {
	                return;
	            }
	            // Look up the previous index and title.
	            var pi = this._currentIndex;
	            var pt = this._titles[pi] || null;
	            // Look up the current index and title.
	            var ci = value;
	            var ct = this._titles[ci] || null;
	            // Update the current index and previous title.
	            this._currentIndex = ci;
	            this._previousTitle = pt;
	            // Schedule an update of the tabs.
	            this.update();
	            // Emit the current changed signal.
	            this._currentChanged.emit({
	                previousIndex: pi, previousTitle: pt,
	                currentIndex: ci, currentTitle: ct
	            });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "orientation", {
	        /**
	         * Get the orientation of the tab bar.
	         *
	         * #### Notes
	         * This controls whether the tabs are arranged in a row or column.
	         */
	        get: function () {
	            return this._orientation;
	        },
	        /**
	         * Set the orientation of the tab bar.
	         *
	         * #### Notes
	         * This controls whether the tabs are arranged in a row or column.
	         */
	        set: function (value) {
	            // Do nothing if the orientation does not change.
	            if (this._orientation === value) {
	                return;
	            }
	            // Release the mouse before making any changes.
	            this._releaseMouse();
	            // Toggle the orientation values.
	            this._orientation = value;
	            this.dataset['orientation'] = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "titles", {
	        /**
	         * A read-only array of the titles in the tab bar.
	         */
	        get: function () {
	            return this._titles;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "contentNode", {
	        /**
	         * The tab bar content node.
	         *
	         * #### Notes
	         * This is the node which holds the tab nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-TabBar-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a tab to the end of the tab bar.
	     *
	     * @param value - The title which holds the data for the tab,
	     *   or an options object to convert to a title.
	     *
	     * @returns The title object added to the tab bar.
	     *
	     * #### Notes
	     * If the title is already added to the tab bar, it will be moved.
	     */
	    TabBar.prototype.addTab = function (value) {
	        return this.insertTab(this._titles.length, value);
	    };
	    /**
	     * Insert a tab into the tab bar at the specified index.
	     *
	     * @param index - The index at which to insert the tab.
	     *
	     * @param value - The title which holds the data for the tab,
	     *   or an options object to convert to a title.
	     *
	     * @returns The title object added to the tab bar.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the tabs.
	     *
	     * If the title is already added to the tab bar, it will be moved.
	     */
	    TabBar.prototype.insertTab = function (index, value) {
	        // Release the mouse before making any changes.
	        this._releaseMouse();
	        // Coerce the value to a title.
	        var title = Private.asTitle(value);
	        // Look up the index of the title.
	        var i = this._titles.indexOf(title);
	        // Clamp the insert index to the array bounds.
	        var j = Math.max(0, Math.min(index, this._titles.length));
	        // If the title is not in the array, insert it.
	        if (i === -1) {
	            // Insert the title into the array.
	            algorithm_1.ArrayExt.insert(this._titles, j, title);
	            // Connect to the title changed signal.
	            title.changed.connect(this._onTitleChanged, this);
	            // Schedule an update of the tabs.
	            this.update();
	            // Adjust the current index for the insert.
	            this._adjustCurrentForInsert(j, title);
	            // Return the title added to the tab bar.
	            return title;
	        }
	        // Otherwise, the title exists in the array and should be moved.
	        // Adjust the index if the location is at the end of the array.
	        if (j === this._titles.length) {
	            j--;
	        }
	        // Bail if there is no effective move.
	        if (i === j) {
	            return title;
	        }
	        // Move the title to the new location.
	        algorithm_1.ArrayExt.move(this._titles, i, j);
	        // Schedule an update of the tabs.
	        this.update();
	        // Adjust the current index for the move.
	        this._adjustCurrentForMove(i, j);
	        // Return the title added to the tab bar.
	        return title;
	    };
	    /**
	     * Remove a tab from the tab bar.
	     *
	     * @param title - The title for the tab to remove.
	     *
	     * #### Notes
	     * This is a no-op if the title is not in the tab bar.
	     */
	    TabBar.prototype.removeTab = function (title) {
	        this.removeTabAt(this._titles.indexOf(title));
	    };
	    /**
	     * Remove the tab at a given index from the tab bar.
	     *
	     * @param index - The index of the tab to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    TabBar.prototype.removeTabAt = function (index) {
	        // Release the mouse before making any changes.
	        this._releaseMouse();
	        // Remove the title from the array.
	        var title = algorithm_1.ArrayExt.removeAt(this._titles, index);
	        // Bail if the index is out of range.
	        if (!title) {
	            return;
	        }
	        // Disconnect from the title changed signal.
	        title.changed.disconnect(this._onTitleChanged, this);
	        // Clear the previous title if it's being removed.
	        if (title === this._previousTitle) {
	            this._previousTitle = null;
	        }
	        // Schedule an update of the tabs.
	        this.update();
	        // Adjust the current index for the remove.
	        this._adjustCurrentForRemove(index, title);
	    };
	    /**
	     * Remove all tabs from the tab bar.
	     */
	    TabBar.prototype.clearTabs = function () {
	        // Bail if there is nothing to remove.
	        if (this._titles.length === 0) {
	            return;
	        }
	        // Release the mouse before making any changes.
	        this._releaseMouse();
	        // Disconnect from the title changed signals.
	        for (var _i = 0, _a = this._titles; _i < _a.length; _i++) {
	            var title = _a[_i];
	            title.changed.disconnect(this._onTitleChanged, this);
	        }
	        // Get the current index and title.
	        var pi = this.currentIndex;
	        var pt = this.currentTitle;
	        // Reset the current index and previous title.
	        this._currentIndex = -1;
	        this._previousTitle = null;
	        // Clear the title array.
	        this._titles.length = 0;
	        // Schedule an update of the tabs.
	        this.update();
	        // If no tab was selected, there's nothing else to do.
	        if (pi === -1) {
	            return;
	        }
	        // Emit the current changed signal.
	        this._currentChanged.emit({
	            previousIndex: pi, previousTitle: pt,
	            currentIndex: -1, currentTitle: null
	        });
	    };
	    /**
	     * Release the mouse and restore the non-dragged tab positions.
	     *
	     * #### Notes
	     * This will cause the tab bar to stop handling mouse events and to
	     * restore the tabs to their non-dragged positions.
	     */
	    TabBar.prototype.releaseMouse = function () {
	        this._releaseMouse();
	    };
	    /**
	     * Handle the DOM events for the tab bar.
	     *
	     * @param event - The DOM event sent to the tab bar.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the tab bar's DOM node.
	     *
	     * This should not be called directly by user code.
	     */
	    TabBar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    TabBar.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    TabBar.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    TabBar.prototype.onUpdateRequest = function (msg) {
	        var titles = this._titles;
	        var renderer = this.renderer;
	        var currentTitle = this.currentTitle;
	        var content = new Array(titles.length);
	        for (var i = 0, n = titles.length; i < n; ++i) {
	            var title = titles[i];
	            var current = title === currentTitle;
	            var zIndex = current ? n : n - i - 1;
	            content[i] = renderer.renderTab({ title: title, current: current, zIndex: zIndex });
	        }
	        virtualdom_1.VirtualDOM.render(content, this.contentNode);
	    };
	    /**
	     * Handle the `'keydown'` event for the tab bar.
	     */
	    TabBar.prototype._evtKeyDown = function (event) {
	        // Stop all input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            this._releaseMouse();
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the tab bar.
	     */
	    TabBar.prototype._evtMouseDown = function (event) {
	        // Do nothing if it's not a left or middle mouse press.
	        if (event.button !== 0 && event.button !== 1) {
	            return;
	        }
	        // Do nothing if a drag is in progress.
	        if (this._dragData) {
	            return;
	        }
	        // Lookup the tab nodes.
	        var tabs = this.contentNode.children;
	        // Find the index of the pressed tab.
	        var index = algorithm_1.ArrayExt.findFirstIndex(tabs, function (tab) {
	            return domutils_1.ElementExt.hitTest(tab, event.clientX, event.clientY);
	        });
	        // Do nothing if the press is not on a tab.
	        if (index === -1) {
	            return;
	        }
	        // Pressing on a tab stops the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Initialize the non-measured parts of the drag data.
	        this._dragData = {
	            tab: tabs[index],
	            index: index,
	            pressX: event.clientX,
	            pressY: event.clientY,
	            tabPos: -1,
	            tabSize: -1,
	            tabPressPos: -1,
	            targetIndex: -1,
	            tabLayout: null,
	            contentRect: null,
	            override: null,
	            dragActive: false,
	            dragAborted: false,
	            detachRequested: false
	        };
	        // Add the document mouse up listener.
	        document.addEventListener('mouseup', this, true);
	        // Do nothing else if the middle button is clicked.
	        if (event.button === 1) {
	            return;
	        }
	        // Do nothing else if the close icon is clicked.
	        var icon = tabs[index].querySelector(this.renderer.closeIconSelector);
	        if (icon && icon.contains(event.target)) {
	            return;
	        }
	        // Add the extra listeners if the tabs are movable.
	        if (this.tabsMovable) {
	            document.addEventListener('mousemove', this, true);
	            document.addEventListener('keydown', this, true);
	            document.addEventListener('contextmenu', this, true);
	        }
	        // Update the current index as appropriate.
	        if (this.allowDeselect && this.currentIndex === index) {
	            this.currentIndex = -1;
	        }
	        else {
	            this.currentIndex = index;
	        }
	        // Do nothing else if there is no current tab.
	        if (this.currentIndex === -1) {
	            return;
	        }
	        // Emit the tab activate request signal.
	        this._tabActivateRequested.emit({
	            index: this.currentIndex, title: this.currentTitle
	        });
	    };
	    /**
	     * Handle the `'mousemove'` event for the tab bar.
	     */
	    TabBar.prototype._evtMouseMove = function (event) {
	        // Do nothing if no drag is in progress.
	        var data = this._dragData;
	        if (!data) {
	            return;
	        }
	        // Suppress the event during a drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Lookup the tab nodes.
	        var tabs = this.contentNode.children;
	        // Bail early if the drag threshold has not been met.
	        if (!data.dragActive && !Private.dragExceeded(data, event)) {
	            return;
	        }
	        // Activate the drag if necessary.
	        if (!data.dragActive) {
	            // Fill in the rest of the drag data measurements.
	            var tabRect = data.tab.getBoundingClientRect();
	            if (this._orientation === 'horizontal') {
	                data.tabPos = data.tab.offsetLeft;
	                data.tabSize = tabRect.width;
	                data.tabPressPos = data.pressX - tabRect.left;
	            }
	            else {
	                data.tabPos = data.tab.offsetTop;
	                data.tabSize = tabRect.height;
	                data.tabPressPos = data.pressY - tabRect.top;
	            }
	            data.tabLayout = Private.snapTabLayout(tabs, this._orientation);
	            data.contentRect = this.contentNode.getBoundingClientRect();
	            data.override = dragdrop_1.Drag.overrideCursor('default');
	            // Add the dragging style classes.
	            data.tab.classList.add('p-mod-dragging');
	            this.addClass('p-mod-dragging');
	            // Mark the drag as active.
	            data.dragActive = true;
	        }
	        // Emit the detach requested signal if the threshold is exceeded.
	        if (!data.detachRequested && Private.detachExceeded(data, event)) {
	            // Only emit the signal once per drag cycle.
	            data.detachRequested = true;
	            // Setup the arguments for the signal.
	            var index = data.index;
	            var clientX = event.clientX;
	            var clientY = event.clientY;
	            var tab = tabs[index];
	            var title = this._titles[index];
	            // Emit the tab detach requested signal.
	            this._tabDetachRequested.emit({ index: index, title: title, tab: tab, clientX: clientX, clientY: clientY });
	            // Bail if the signal handler aborted the drag.
	            if (data.dragAborted) {
	                return;
	            }
	        }
	        // Update the positions of the tabs.
	        Private.layoutTabs(tabs, data, event, this._orientation);
	    };
	    /**
	     * Handle the `'mouseup'` event for the document.
	     */
	    TabBar.prototype._evtMouseUp = function (event) {
	        var _this = this;
	        // Do nothing if it's not a left or middle mouse release.
	        if (event.button !== 0 && event.button !== 1) {
	            return;
	        }
	        // Do nothing if no drag is in progress.
	        var data = this._dragData;
	        if (!data) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Remove the extra mouse event listeners.
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	        // Handle a release when the drag is not active.
	        if (!data.dragActive) {
	            // Clear the drag data.
	            this._dragData = null;
	            // Lookup the tab nodes.
	            var tabs = this.contentNode.children;
	            // Find the index of the released tab.
	            var index = algorithm_1.ArrayExt.findFirstIndex(tabs, function (tab) {
	                return domutils_1.ElementExt.hitTest(tab, event.clientX, event.clientY);
	            });
	            // Do nothing if the release is not on the original pressed tab.
	            if (index !== data.index) {
	                return;
	            }
	            // Ignore the release if the title is not closable.
	            var title = this._titles[index];
	            if (!title.closable) {
	                return;
	            }
	            // Emit the close requested signal if the middle button is released.
	            if (event.button === 1) {
	                this._tabCloseRequested.emit({ index: index, title: title });
	                return;
	            }
	            // Emit the close requested signal if the close icon was released.
	            var icon = tabs[index].querySelector(this.renderer.closeIconSelector);
	            if (icon && icon.contains(event.target)) {
	                this._tabCloseRequested.emit({ index: index, title: title });
	                return;
	            }
	            // Otherwise, there is nothing left to do.
	            return;
	        }
	        // Do nothing if the left button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Position the tab at its final resting position.
	        Private.finalizeTabPosition(data, this._orientation);
	        // Remove the dragging class from the tab so it can be transitioned.
	        data.tab.classList.remove('p-mod-dragging');
	        // Parse the transition duration for releasing the tab.
	        var duration = Private.parseTransitionDuration(data.tab);
	        // Complete the release on a timer to allow the tab to transition.
	        setTimeout(function () {
	            // Do nothing if the drag has been aborted.
	            if (data.dragAborted) {
	                return;
	            }
	            // Clear the drag data reference.
	            _this._dragData = null;
	            // Reset the positions of the tabs.
	            Private.resetTabPositions(_this.contentNode.children, _this._orientation);
	            // Clear the cursor grab.
	            data.override.dispose();
	            // Remove the remaining dragging style.
	            _this.removeClass('p-mod-dragging');
	            // If the tab was not moved, there is nothing else to do.
	            var i = data.index;
	            var j = data.targetIndex;
	            if (j === -1 || i === j) {
	                return;
	            }
	            // Move the title to the new locations.
	            algorithm_1.ArrayExt.move(_this._titles, i, j);
	            // Adjust the current index for the move.
	            _this._adjustCurrentForMove(i, j);
	            // Emit the tab moved signal.
	            _this._tabMoved.emit({
	                fromIndex: i, toIndex: j, title: _this._titles[j]
	            });
	            // Update the tabs immediately to prevent flicker.
	            messaging_1.MessageLoop.sendMessage(_this, widget_1.Widget.Msg.UpdateRequest);
	        }, duration);
	    };
	    /**
	     * Release the mouse and restore the non-dragged tab positions.
	     */
	    TabBar.prototype._releaseMouse = function () {
	        // Do nothing if no drag is in progress.
	        var data = this._dragData;
	        if (!data) {
	            return;
	        }
	        // Clear the drag data reference.
	        this._dragData = null;
	        // Remove the extra mouse listeners.
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	        // Indicate the drag has been aborted. This allows the mouse
	        // event handlers to return early when the drag is canceled.
	        data.dragAborted = true;
	        // If the drag is not active, there's nothing more to do.
	        if (!data.dragActive) {
	            return;
	        }
	        // Reset the tabs to their non-dragged positions.
	        Private.resetTabPositions(this.contentNode.children, this._orientation);
	        // Clear the cursor override.
	        data.override.dispose();
	        // Clear the dragging style classes.
	        data.tab.classList.remove('p-mod-dragging');
	        this.removeClass('p-mod-dragging');
	    };
	    /**
	     * Adjust the current index for a tab insert operation.
	     *
	     * This method accounts for the tab bar's insertion behavior when
	     * adjusting the current index and emitting the changed signal.
	     */
	    TabBar.prototype._adjustCurrentForInsert = function (i, title) {
	        // Lookup commonly used variables.
	        var ct = this.currentTitle;
	        var ci = this._currentIndex;
	        var bh = this.insertBehavior;
	        // Handle the behavior where the new tab is always selected,
	        // or the behavior where the new tab is selected if needed.
	        if (bh === 'select-tab' || (bh === 'select-tab-if-needed' && ci === -1)) {
	            this._currentIndex = i;
	            this._previousTitle = ct;
	            this._currentChanged.emit({
	                previousIndex: ci, previousTitle: ct,
	                currentIndex: i, currentTitle: title
	            });
	            return;
	        }
	        // Otherwise, silently adjust the current index if needed.
	        if (ci >= i) {
	            this._currentIndex++;
	        }
	    };
	    /**
	     * Adjust the current index for a tab move operation.
	     *
	     * This method will not cause the actual current tab to change.
	     * It silently adjusts the index to account for the given move.
	     */
	    TabBar.prototype._adjustCurrentForMove = function (i, j) {
	        if (this._currentIndex === i) {
	            this._currentIndex = j;
	        }
	        else if (this._currentIndex < i && this._currentIndex >= j) {
	            this._currentIndex++;
	        }
	        else if (this._currentIndex > i && this._currentIndex <= j) {
	            this._currentIndex--;
	        }
	    };
	    /**
	     * Adjust the current index for a tab remove operation.
	     *
	     * This method accounts for the tab bar's remove behavior when
	     * adjusting the current index and emitting the changed signal.
	     */
	    TabBar.prototype._adjustCurrentForRemove = function (i, title) {
	        // Lookup commonly used variables.
	        var ci = this._currentIndex;
	        var bh = this.removeBehavior;
	        // Silently adjust the index if the current tab is not removed.
	        if (ci !== i) {
	            if (ci > i) {
	                this._currentIndex--;
	            }
	            return;
	        }
	        // No tab gets selected if the tab bar is empty.
	        if (this._titles.length === 0) {
	            this._currentIndex = -1;
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: -1, currentTitle: null
	            });
	            return;
	        }
	        // Handle behavior where the next sibling tab is selected.
	        if (bh === 'select-tab-after') {
	            this._currentIndex = Math.min(i, this._titles.length - 1);
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: this._currentIndex, currentTitle: this.currentTitle
	            });
	            return;
	        }
	        // Handle behavior where the previous sibling tab is selected.
	        if (bh === 'select-tab-before') {
	            this._currentIndex = Math.max(0, i - 1);
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: this._currentIndex, currentTitle: this.currentTitle
	            });
	            return;
	        }
	        // Handle behavior where the previous history tab is selected.
	        if (bh === 'select-previous-tab') {
	            if (this._previousTitle) {
	                this._currentIndex = this._titles.indexOf(this._previousTitle);
	                this._previousTitle = null;
	            }
	            else {
	                this._currentIndex = Math.min(i, this._titles.length - 1);
	            }
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: this._currentIndex, currentTitle: this.currentTitle
	            });
	            return;
	        }
	        // Otherwise, no tab gets selected.
	        this._currentIndex = -1;
	        this._currentChanged.emit({
	            previousIndex: i, previousTitle: title,
	            currentIndex: -1, currentTitle: null
	        });
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    TabBar.prototype._onTitleChanged = function (sender) {
	        this.update();
	    };
	    return TabBar;
	}(widget_1.Widget));
	exports.TabBar = TabBar;
	/**
	 * The namespace for the `TabBar` class statics.
	 */
	(function (TabBar) {
	    /**
	     * The default implementation of `IRenderer`.
	     *
	     * #### Notes
	     * Subclasses are free to reimplement rendering methods as needed.
	     */
	    var Renderer = (function () {
	        /**
	         * Construct a new renderer.
	         */
	        function Renderer() {
	            /**
	             * A selector which matches the close icon node in a tab.
	             */
	            this.closeIconSelector = '.p-TabBar-tabCloseIcon';
	            this._tabID = 0;
	            this._tabKeys = new WeakMap();
	        }
	        /**
	         * Render the virtual element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab.
	         */
	        Renderer.prototype.renderTab = function (data) {
	            var title = data.title.caption;
	            var key = this.createTabKey(data);
	            var style = this.createTabStyle(data);
	            var className = this.createTabClass(data);
	            var dataset = this.createTabDataset(data);
	            return (virtualdom_1.h.li({ key: key, className: className, title: title, style: style, dataset: dataset }, this.renderIcon(data), this.renderLabel(data), this.renderCloseIcon(data)));
	        };
	        /**
	         * Render the icon element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab icon.
	         */
	        Renderer.prototype.renderIcon = function (data) {
	            var className = this.createIconClass(data);
	            return virtualdom_1.h.div({ className: className }, data.title.iconLabel);
	        };
	        /**
	         * Render the label element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab label.
	         */
	        Renderer.prototype.renderLabel = function (data) {
	            return virtualdom_1.h.div({ className: 'p-TabBar-tabLabel' }, data.title.label);
	        };
	        /**
	         * Render the close icon element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab close icon.
	         */
	        Renderer.prototype.renderCloseIcon = function (data) {
	            return virtualdom_1.h.div({ className: 'p-TabBar-tabCloseIcon' });
	        };
	        /**
	         * Create a unique render key for the tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The unique render key for the tab.
	         *
	         * #### Notes
	         * This method caches the key against the tab title the first time
	         * the key is generated. This enables efficient rendering of moved
	         * tabs and avoids subtle hover style artifacts.
	         */
	        Renderer.prototype.createTabKey = function (data) {
	            var key = this._tabKeys.get(data.title);
	            if (key === undefined) {
	                key = "tab-key-" + this._tabID++;
	                this._tabKeys.set(data.title, key);
	            }
	            return key;
	        };
	        /**
	         * Create the inline style object for a tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The inline style data for the tab.
	         */
	        Renderer.prototype.createTabStyle = function (data) {
	            return { zIndex: "" + data.zIndex };
	        };
	        /**
	         * Create the class name for the tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The full class name for the tab.
	         */
	        Renderer.prototype.createTabClass = function (data) {
	            var name = 'p-TabBar-tab';
	            if (data.title.className) {
	                name += " " + data.title.className;
	            }
	            if (data.title.closable) {
	                name += ' p-mod-closable';
	            }
	            if (data.current) {
	                name += ' p-mod-current';
	            }
	            return name;
	        };
	        /**
	         * Create the dataset for a tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The dataset for the tab.
	         */
	        Renderer.prototype.createTabDataset = function (data) {
	            return data.title.dataset;
	        };
	        /**
	         * Create the class name for the tab icon.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The full class name for the tab icon.
	         */
	        Renderer.prototype.createIconClass = function (data) {
	            var name = 'p-TabBar-tabIcon';
	            var extra = data.title.iconClass;
	            return extra ? name + " " + extra : name;
	        };
	        return Renderer;
	    }());
	    TabBar.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    TabBar.defaultRenderer = new Renderer();
	})(TabBar = exports.TabBar || (exports.TabBar = {}));
	exports.TabBar = TabBar;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The start drag distance threshold.
	     */
	    Private.DRAG_THRESHOLD = 5;
	    /**
	     * The detach distance threshold.
	     */
	    Private.DETACH_THRESHOLD = 20;
	    /**
	     * Create the DOM node for a tab bar.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = 'p-TabBar-content';
	        node.appendChild(content);
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Coerce a title or options into a real title.
	     */
	    function asTitle(value) {
	        return value instanceof title_1.Title ? value : new title_1.Title(value);
	    }
	    Private.asTitle = asTitle;
	    /**
	     * Parse the transition duration for a tab node.
	     */
	    function parseTransitionDuration(tab) {
	        var style = window.getComputedStyle(tab);
	        return 1000 * (parseFloat(style.transitionDuration) || 0);
	    }
	    Private.parseTransitionDuration = parseTransitionDuration;
	    /**
	     * Get a snapshot of the current tab layout values.
	     */
	    function snapTabLayout(tabs, orientation) {
	        var layout = new Array(tabs.length);
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            var node = tabs[i];
	            var style = window.getComputedStyle(node);
	            if (orientation === 'horizontal') {
	                layout[i] = {
	                    pos: node.offsetLeft,
	                    size: node.offsetWidth,
	                    margin: parseFloat(style.marginLeft) || 0
	                };
	            }
	            else {
	                layout[i] = {
	                    pos: node.offsetTop,
	                    size: node.offsetHeight,
	                    margin: parseFloat(style.marginTop) || 0
	                };
	            }
	        }
	        return layout;
	    }
	    Private.snapTabLayout = snapTabLayout;
	    /**
	     * Test if the event exceeds the drag threshold.
	     */
	    function dragExceeded(data, event) {
	        var dx = Math.abs(event.clientX - data.pressX);
	        var dy = Math.abs(event.clientY - data.pressY);
	        return dx >= Private.DRAG_THRESHOLD || dy >= Private.DRAG_THRESHOLD;
	    }
	    Private.dragExceeded = dragExceeded;
	    /**
	     * Test if the event exceeds the drag detach threshold.
	     */
	    function detachExceeded(data, event) {
	        var rect = data.contentRect;
	        return ((event.clientX < rect.left - Private.DETACH_THRESHOLD) ||
	            (event.clientX >= rect.right + Private.DETACH_THRESHOLD) ||
	            (event.clientY < rect.top - Private.DETACH_THRESHOLD) ||
	            (event.clientY >= rect.bottom + Private.DETACH_THRESHOLD));
	    }
	    Private.detachExceeded = detachExceeded;
	    /**
	     * Update the relative tab positions and computed target index.
	     */
	    function layoutTabs(tabs, data, event, orientation) {
	        // Compute the orientation-sensitive values.
	        var pressPos;
	        var localPos;
	        var clientPos;
	        var clientSize;
	        if (orientation === 'horizontal') {
	            pressPos = data.pressX;
	            localPos = event.clientX - data.contentRect.left;
	            clientPos = event.clientX;
	            clientSize = data.contentRect.width;
	        }
	        else {
	            pressPos = data.pressY;
	            localPos = event.clientY - data.contentRect.top;
	            clientPos = event.clientY;
	            clientSize = data.contentRect.height;
	        }
	        // Compute the target data.
	        var targetIndex = data.index;
	        var targetPos = localPos - data.tabPressPos;
	        var targetEnd = targetPos + data.tabSize;
	        // Update the relative tab positions.
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            var pxPos = void 0;
	            var layout = data.tabLayout[i];
	            var threshold = layout.pos + (layout.size >> 1);
	            if (i < data.index && targetPos < threshold) {
	                pxPos = data.tabSize + data.tabLayout[i + 1].margin + "px";
	                targetIndex = Math.min(targetIndex, i);
	            }
	            else if (i > data.index && targetEnd > threshold) {
	                pxPos = -data.tabSize - layout.margin + "px";
	                targetIndex = Math.max(targetIndex, i);
	            }
	            else if (i === data.index) {
	                var ideal = clientPos - pressPos;
	                var limit = clientSize - (data.tabPos + data.tabSize);
	                pxPos = Math.max(-data.tabPos, Math.min(ideal, limit)) + "px";
	            }
	            else {
	                pxPos = '';
	            }
	            if (orientation === 'horizontal') {
	                tabs[i].style.left = pxPos;
	            }
	            else {
	                tabs[i].style.top = pxPos;
	            }
	        }
	        // Update the computed target index.
	        data.targetIndex = targetIndex;
	    }
	    Private.layoutTabs = layoutTabs;
	    /**
	     * Position the drag tab at its final resting relative position.
	     */
	    function finalizeTabPosition(data, orientation) {
	        // Compute the orientation-sensitive client size.
	        var clientSize;
	        if (orientation === 'horizontal') {
	            clientSize = data.contentRect.width;
	        }
	        else {
	            clientSize = data.contentRect.height;
	        }
	        // Compute the ideal final tab position.
	        var ideal;
	        if (data.targetIndex === data.index) {
	            ideal = 0;
	        }
	        else if (data.targetIndex > data.index) {
	            var tgt = data.tabLayout[data.targetIndex];
	            ideal = tgt.pos + tgt.size - data.tabSize - data.tabPos;
	        }
	        else {
	            var tgt = data.tabLayout[data.targetIndex];
	            ideal = tgt.pos - data.tabPos;
	        }
	        // Compute the tab position limit.
	        var limit = clientSize - (data.tabPos + data.tabSize);
	        var final = Math.max(-data.tabPos, Math.min(ideal, limit));
	        // Set the final orientation-sensitive position.
	        if (orientation === 'horizontal') {
	            data.tab.style.left = final + "px";
	        }
	        else {
	            data.tab.style.top = final + "px";
	        }
	    }
	    Private.finalizeTabPosition = finalizeTabPosition;
	    /**
	     * Reset the relative positions of the given tabs.
	     */
	    function resetTabPositions(tabs, orientation) {
	        algorithm_1.each(tabs, function (tab) {
	            if (orientation === 'horizontal') {
	                tab.style.left = '';
	            }
	            else {
	                tab.style.top = '';
	            }
	        });
	    }
	    Private.resetTabPositions = resetTabPositions;
	})(Private || (Private = {}));


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

	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var signaling_1 = __webpack_require__(201);
	/**
	 * A class which tracks focus among a set of widgets.
	 *
	 * This class is useful when code needs to keep track of the most
	 * recently focused widget(s) among a set of related widgets.
	 */
	var FocusTracker = (function () {
	    /**
	     * Construct a new focus tracker.
	     */
	    function FocusTracker() {
	        this._counter = 0;
	        this._widgets = [];
	        this._activeWidget = null;
	        this._currentWidget = null;
	        this._numbers = new Map();
	        this._nodes = new Map();
	        this._activeChanged = new signaling_1.Signal(this);
	        this._currentChanged = new signaling_1.Signal(this);
	    }
	    /**
	     * Dispose of the resources held by the tracker.
	     */
	    FocusTracker.prototype.dispose = function () {
	        var _this = this;
	        // Do nothing if the tracker is already disposed.
	        if (this._counter < 0) {
	            return;
	        }
	        // Mark the tracker as disposed.
	        this._counter = -1;
	        // Clear the connections for the tracker.
	        signaling_1.Signal.clearData(this);
	        // Remove all event listeners.
	        algorithm_1.each(this._widgets, function (w) {
	            w.node.removeEventListener('focus', _this, true);
	            w.node.removeEventListener('blur', _this, true);
	        });
	        // Clear the internal data structures.
	        this._activeWidget = null;
	        this._currentWidget = null;
	        this._nodes.clear();
	        this._numbers.clear();
	        this._widgets.length = 0;
	    };
	    Object.defineProperty(FocusTracker.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current widget has changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "activeChanged", {
	        /**
	         * A signal emitted when the active widget has changed.
	         */
	        get: function () {
	            return this._activeChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "isDisposed", {
	        /**
	         * A flag indicating whether the tracker is disposed.
	         */
	        get: function () {
	            return this._counter < 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "currentWidget", {
	        /**
	         * The current widget in the tracker.
	         *
	         * #### Notes
	         * The current widget is the widget among the tracked widgets which
	         * has the *descendant node* which has most recently been focused.
	         *
	         * The current widget will not be updated if the node loses focus. It
	         * will only be updated when a different tracked widget gains focus.
	         *
	         * If the current widget is removed from the tracker, the previous
	         * current widget will be restored.
	         *
	         * This behavior is intended to follow a user's conceptual model of
	         * a semantically "current" widget, where the "last thing of type X"
	         * to be interacted with is the "current instance of X", regardless
	         * of whether that instance still has focus.
	         */
	        get: function () {
	            return this._currentWidget;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "activeWidget", {
	        /**
	         * The active widget in the tracker.
	         *
	         * #### Notes
	         * The active widget is the widget among the tracked widgets which
	         * has the *descendant node* which is currently focused.
	         */
	        get: function () {
	            return this._activeWidget;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "widgets", {
	        /**
	         * A read only array of the widgets being tracked.
	         */
	        get: function () {
	            return this._widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the focus number for a particular widget in the tracker.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The focus number for the given widget, or `-1` if the
	     *   widget has not had focus since being added to the tracker, or
	     *   is not contained by the tracker.
	     *
	     * #### Notes
	     * The focus number indicates the relative order in which the widgets
	     * have gained focus. A widget with a larger number has gained focus
	     * more recently than a widget with a smaller number.
	     *
	     * The `currentWidget` will always have the largest focus number.
	     *
	     * All widgets start with a focus number of `-1`, which indicates that
	     * the widget has not been focused since being added to the tracker.
	     */
	    FocusTracker.prototype.focusNumber = function (widget) {
	        var n = this._numbers.get(widget);
	        return n === undefined ? -1 : n;
	    };
	    /**
	     * Test whether the focus tracker contains a given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns `true` if the widget is tracked, `false` otherwise.
	     */
	    FocusTracker.prototype.has = function (widget) {
	        return this._numbers.has(widget);
	    };
	    /**
	     * Add a widget to the focus tracker.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * A widget will be automatically removed from the tracker if it
	     * is disposed after being added.
	     *
	     * If the widget is already tracked, this is a no-op.
	     */
	    FocusTracker.prototype.add = function (widget) {
	        // Do nothing if the widget is already tracked.
	        if (this._numbers.has(widget)) {
	            return;
	        }
	        // Test whether the widget has focus.
	        var focused = widget.node.contains(document.activeElement);
	        // Set up the initial focus number.
	        var n = focused ? this._counter++ : -1;
	        // Add the widget to the internal data structures.
	        this._widgets.push(widget);
	        this._numbers.set(widget, n);
	        this._nodes.set(widget.node, widget);
	        // Set up the event listeners. The capturing phase must be used
	        // since the 'focus' and 'blur' events don't bubble and Firefox
	        // doesn't support the 'focusin' or 'focusout' events.
	        widget.node.addEventListener('focus', this, true);
	        widget.node.addEventListener('blur', this, true);
	        // Connect the disposed signal handler.
	        widget.disposed.connect(this._onWidgetDisposed, this);
	        // Set the current and active widgets if needed.
	        if (focused) {
	            this._setWidgets(widget, widget);
	        }
	    };
	    /**
	     * Remove a widget from the focus tracker.
	     *
	     * #### Notes
	     * If the widget is the `currentWidget`, the previous current widget
	     * will become the new `currentWidget`.
	     *
	     * A widget will be automatically removed from the tracker if it
	     * is disposed after being added.
	     *
	     * If the widget is not tracked, this is a no-op.
	     */
	    FocusTracker.prototype.remove = function (widget) {
	        var _this = this;
	        // Bail early if the widget is not tracked.
	        if (!this._numbers.has(widget)) {
	            return;
	        }
	        // Disconnect the disposed signal handler.
	        widget.disposed.disconnect(this._onWidgetDisposed, this);
	        // Remove the event listeners.
	        widget.node.removeEventListener('focus', this, true);
	        widget.node.removeEventListener('blur', this, true);
	        // Remove the widget from the internal data structures.
	        algorithm_1.ArrayExt.removeFirstOf(this._widgets, widget);
	        this._nodes.delete(widget.node);
	        this._numbers.delete(widget);
	        // Bail early if the widget is not the current widget.
	        if (this._currentWidget !== widget) {
	            return;
	        }
	        // Filter the widgets for those which have had focus.
	        var valid = algorithm_1.filter(this._widgets, function (w) { return _this._numbers.get(w) !== -1; });
	        // Get the valid widget with the max focus number.
	        var previous = algorithm_1.max(valid, function (first, second) {
	            var a = _this._numbers.get(first);
	            var b = _this._numbers.get(second);
	            return a - b;
	        }) || null;
	        // Set the current and active widgets.
	        this._setWidgets(previous, null);
	    };
	    /**
	     * Handle the DOM events for the focus tracker.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the tracked nodes. It should
	     * not be called directly by user code.
	     */
	    FocusTracker.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'focus':
	                this._evtFocus(event);
	                break;
	            case 'blur':
	                this._evtBlur(event);
	                break;
	        }
	    };
	    /**
	     * Set the current and active widgets for the tracker.
	     */
	    FocusTracker.prototype._setWidgets = function (current, active) {
	        // Swap the current widget.
	        var oldCurrent = this._currentWidget;
	        this._currentWidget = current;
	        // Swap the active widget.
	        var oldActive = this._activeWidget;
	        this._activeWidget = active;
	        // Emit the `currentChanged` signal if needed.
	        if (oldCurrent !== current) {
	            this._currentChanged.emit({ oldValue: oldCurrent, newValue: current });
	        }
	        // Emit the `activeChanged` signal if needed.
	        if (oldActive !== active) {
	            this._activeChanged.emit({ oldValue: oldActive, newValue: active });
	        }
	    };
	    /**
	     * Handle the `'focus'` event for a tracked widget.
	     */
	    FocusTracker.prototype._evtFocus = function (event) {
	        // Find the widget which gained focus, which is known to exist.
	        var widget = this._nodes.get(event.currentTarget);
	        // Update the focus number if necessary.
	        if (widget !== this._currentWidget) {
	            this._numbers.set(widget, this._counter++);
	        }
	        // Set the current and active widgets.
	        this._setWidgets(widget, widget);
	    };
	    /**
	     * Handle the `'blur'` event for a tracked widget.
	     */
	    FocusTracker.prototype._evtBlur = function (event) {
	        // Find the widget which lost focus, which is known to exist.
	        var widget = this._nodes.get(event.currentTarget);
	        // Get the node which being focused after this blur.
	        var focusTarget = event.relatedTarget;
	        // If no other node is being focused, clear the active widget.
	        if (!focusTarget) {
	            this._setWidgets(this._currentWidget, null);
	            return;
	        }
	        // Bail if the focus widget is not changing.
	        if (widget.node.contains(focusTarget)) {
	            return;
	        }
	        // If no tracked widget is being focused, clear the active widget.
	        if (!algorithm_1.find(this._widgets, function (w) { return w.node.contains(focusTarget); })) {
	            this._setWidgets(this._currentWidget, null);
	            return;
	        }
	    };
	    /**
	     * Handle the `disposed` signal for a tracked widget.
	     */
	    FocusTracker.prototype._onWidgetDisposed = function (sender) {
	        this.remove(sender);
	    };
	    return FocusTracker;
	}());
	exports.FocusTracker = FocusTracker;


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var messaging_1 = __webpack_require__(196);
	var properties_1 = __webpack_require__(199);
	var boxengine_1 = __webpack_require__(173);
	var layout_1 = __webpack_require__(200);
	var widget_1 = __webpack_require__(202);
	/**
	 * A layout which arranges its widgets in a grid.
	 */
	var GridLayout = (function (_super) {
	    __extends(GridLayout, _super);
	    /**
	     * Construct a new grid layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function GridLayout(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, options) || this;
	        _this._dirty = false;
	        _this._rowSpacing = 4;
	        _this._columnSpacing = 4;
	        _this._items = [];
	        _this._rowStarts = [];
	        _this._columnStarts = [];
	        _this._rowSizers = [new boxengine_1.BoxSizer()];
	        _this._columnSizers = [new boxengine_1.BoxSizer()];
	        _this._box = null;
	        if (options.rowCount !== undefined) {
	            Private.reallocSizers(_this._rowSizers, options.rowCount);
	        }
	        if (options.columnCount !== undefined) {
	            Private.reallocSizers(_this._columnSizers, options.columnCount);
	        }
	        if (options.rowSpacing !== undefined) {
	            _this._rowSpacing = Private.clampValue(options.rowSpacing);
	        }
	        if (options.columnSpacing !== undefined) {
	            _this._columnSpacing = Private.clampValue(options.columnSpacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    GridLayout.prototype.dispose = function () {
	        // Dispose of the widgets and layout items.
	        algorithm_1.each(this._items, function (item) {
	            var widget = item.widget;
	            item.dispose();
	            widget.dispose();
	        });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        this._rowStarts.length = 0;
	        this._rowSizers.length = 0;
	        this._columnStarts.length = 0;
	        this._columnSizers.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(GridLayout.prototype, "rowCount", {
	        /**
	         * Get the number of rows in the layout.
	         */
	        get: function () {
	            return this._rowSizers.length;
	        },
	        /**
	         * Set the number of rows in the layout.
	         *
	         * #### Notes
	         * The minimum row count is `1`.
	         */
	        set: function (value) {
	            // Do nothing if the row count does not change.
	            if (value === this.rowCount) {
	                return;
	            }
	            // Reallocate the row sizers.
	            Private.reallocSizers(this._rowSizers, value);
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(GridLayout.prototype, "columnCount", {
	        /**
	         * Get the number of columns in the layout.
	         */
	        get: function () {
	            return this._columnSizers.length;
	        },
	        /**
	         * Set the number of columns in the layout.
	         *
	         * #### Notes
	         * The minimum column count is `1`.
	         */
	        set: function (value) {
	            // Do nothing if the column count does not change.
	            if (value === this.columnCount) {
	                return;
	            }
	            // Reallocate the column sizers.
	            Private.reallocSizers(this._columnSizers, value);
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(GridLayout.prototype, "rowSpacing", {
	        /**
	         * Get the row spacing for the layout.
	         */
	        get: function () {
	            return this._rowSpacing;
	        },
	        /**
	         * Set the row spacing for the layout.
	         */
	        set: function (value) {
	            // Clamp the spacing to the allowed range.
	            value = Private.clampValue(value);
	            // Bail if the spacing does not change
	            if (this._rowSpacing === value) {
	                return;
	            }
	            // Update the internal spacing.
	            this._rowSpacing = value;
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(GridLayout.prototype, "columnSpacing", {
	        /**
	         * Get the column spacing for the layout.
	         */
	        get: function () {
	            return this._columnSpacing;
	        },
	        /**
	         * Set the col spacing for the layout.
	         */
	        set: function (value) {
	            // Clamp the spacing to the allowed range.
	            value = Private.clampValue(value);
	            // Bail if the spacing does not change
	            if (this._columnSpacing === value) {
	                return;
	            }
	            // Update the internal spacing.
	            this._columnSpacing = value;
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the stretch factor for a specific row.
	     *
	     * @param index - The row index of interest.
	     *
	     * @returns The stretch factor for the row.
	     *
	     * #### Notes
	     * This returns `-1` if the index is out of range.
	     */
	    GridLayout.prototype.rowStretch = function (index) {
	        var sizer = this._rowSizers[index];
	        return sizer ? sizer.stretch : -1;
	    };
	    /**
	     * Set the stretch factor for a specific row.
	     *
	     * @param index - The row index of interest.
	     *
	     * @param value - The stretch factor for the row.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    GridLayout.prototype.setRowStretch = function (index, value) {
	        // Look up the row sizer.
	        var sizer = this._rowSizers[index];
	        // Bail if the index is out of range.
	        if (!sizer) {
	            return;
	        }
	        // Clamp the value to the allowed range.
	        value = Private.clampValue(value);
	        // Bail if the stretch does not change.
	        if (sizer.stretch === value) {
	            return;
	        }
	        // Update the sizer stretch.
	        sizer.stretch = value;
	        // Schedule an update of the parent.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Get the stretch factor for a specific column.
	     *
	     * @param index - The column index of interest.
	     *
	     * @returns The stretch factor for the column.
	     *
	     * #### Notes
	     * This returns `-1` if the index is out of range.
	     */
	    GridLayout.prototype.columnStretch = function (index) {
	        var sizer = this._columnSizers[index];
	        return sizer ? sizer.stretch : -1;
	    };
	    /**
	     * Set the stretch factor for a specific column.
	     *
	     * @param index - The column index of interest.
	     *
	     * @param value - The stretch factor for the column.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    GridLayout.prototype.setColumnStretch = function (index, value) {
	        // Look up the column sizer.
	        var sizer = this._columnSizers[index];
	        // Bail if the index is out of range.
	        if (!sizer) {
	            return;
	        }
	        // Clamp the value to the allowed range.
	        value = Private.clampValue(value);
	        // Bail if the stretch does not change.
	        if (sizer.stretch === value) {
	            return;
	        }
	        // Update the sizer stretch.
	        sizer.stretch = value;
	        // Schedule an update of the parent.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Create an iterator over the widgets in the layout.
	     *
	     * @returns A new iterator over the widgets in the layout.
	     */
	    GridLayout.prototype.iter = function () {
	        return algorithm_1.map(this._items, function (item) { return item.widget; });
	    };
	    /**
	     * Add a widget to the grid layout.
	     *
	     * @param widget - The widget to add to the layout.
	     *
	     * #### Notes
	     * If the widget is already contained in the layout, this is no-op.
	     */
	    GridLayout.prototype.addWidget = function (widget) {
	        // Look up the index for the widget.
	        var i = algorithm_1.ArrayExt.findFirstIndex(this._items, function (it) { return it.widget === widget; });
	        // Bail if the widget is already in the layout.
	        if (i !== -1) {
	            return;
	        }
	        // Add the widget to the layout.
	        this._items.push(new layout_1.LayoutItem(widget));
	        // Attach the widget to the parent.
	        if (this.parent) {
	            this.attachWidget(widget);
	        }
	    };
	    /**
	     * Remove a widget from the grid layout.
	     *
	     * @param widget - The widget to remove from the layout.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     */
	    GridLayout.prototype.removeWidget = function (widget) {
	        // Look up the index for the widget.
	        var i = algorithm_1.ArrayExt.findFirstIndex(this._items, function (it) { return it.widget === widget; });
	        // Bail if the widget is not in the layout.
	        if (i !== -1) {
	            return;
	        }
	        // Remove the widget from the layout.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, i);
	        // Detach the widget from the parent.
	        if (this.parent) {
	            this.detachWidget(widget);
	        }
	        // Dispose the layout item.
	        item.dispose();
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    GridLayout.prototype.init = function () {
	        var _this = this;
	        _super.prototype.init.call(this);
	        algorithm_1.each(this, function (widget) { _this.attachWidget(widget); });
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param widget - The widget to attach to the parent.
	     */
	    GridLayout.prototype.attachWidget = function (widget) {
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param widget - The widget to detach from the parent.
	     */
	    GridLayout.prototype.detachWidget = function (widget) {
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    GridLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    GridLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    GridLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    GridLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    GridLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    GridLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    GridLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    GridLayout.prototype._fit = function () {
	        // Reset the min sizes of the sizers.
	        for (var i = 0, n = this.rowCount; i < n; ++i) {
	            this._rowSizers[i].minSize = 0;
	        }
	        for (var i = 0, n = this.columnCount; i < n; ++i) {
	            this._columnSizers[i].minSize = 0;
	        }
	        // Filter for the visible layout items.
	        var items = this._items.filter(function (it) { return !it.isHidden; });
	        // Fit the layout items.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            items[i].fit();
	        }
	        // Get the max row and column index.
	        var maxRow = this.rowCount - 1;
	        var maxCol = this.columnCount - 1;
	        // Sort the items by row span.
	        items.sort(Private.rowSpanCmp);
	        // Update the min sizes of the row sizers.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = items[i];
	            // Get the row bounds for the item.
	            var config = GridLayout.getCellConfig(item.widget);
	            var r1 = Math.min(config.row, maxRow);
	            var r2 = Math.min(config.row + config.rowSpan - 1, maxRow);
	            // Distribute the minimum height to the sizers as needed.
	            Private.distributeMin(this._rowSizers, r1, r2, item.minHeight);
	        }
	        // Sort the items by column span.
	        items.sort(Private.columnSpanCmp);
	        // Update the min sizes of the column sizers.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = items[i];
	            // Get the column bounds for the item.
	            var config = GridLayout.getCellConfig(item.widget);
	            var c1 = Math.min(config.column, maxCol);
	            var c2 = Math.min(config.column + config.columnSpan - 1, maxCol);
	            // Distribute the minimum width to the sizers as needed.
	            Private.distributeMin(this._columnSizers, c1, c2, item.minWidth);
	        }
	        // If no size constraint is needed, just update the parent.
	        if (this.fitPolicy === 'set-no-constraint') {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	            return;
	        }
	        // Set up the computed min size.
	        var minH = maxRow * this._rowSpacing;
	        var minW = maxCol * this._columnSpacing;
	        // Add the sizer minimums to the computed min size.
	        for (var i = 0, n = this.rowCount; i < n; ++i) {
	            minH += this._rowSizers[i].minSize;
	        }
	        for (var i = 0, n = this.columnCount; i < n; ++i) {
	            minW += this._columnSizers[i].minSize;
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    GridLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the layout area adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Get the max row and column index.
	        var maxRow = this.rowCount - 1;
	        var maxCol = this.columnCount - 1;
	        // Compute the total fixed row and column space.
	        var fixedRowSpace = maxRow * this._rowSpacing;
	        var fixedColSpace = maxCol * this._columnSpacing;
	        // Distribute the available space to the box sizers.
	        boxengine_1.BoxEngine.calc(this._rowSizers, Math.max(0, height - fixedRowSpace));
	        boxengine_1.BoxEngine.calc(this._columnSizers, Math.max(0, width - fixedColSpace));
	        // Update the row start positions.
	        for (var i = 0, pos = top, n = this.rowCount; i < n; ++i) {
	            this._rowStarts[i] = pos;
	            pos += this._rowSizers[i].size + this._rowSpacing;
	        }
	        // Update the column start positions.
	        for (var i = 0, pos = left, n = this.columnCount; i < n; ++i) {
	            this._columnStarts[i] = pos;
	            pos += this._columnSizers[i].size + this._columnSpacing;
	        }
	        // Update the geometry of the layout items.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Fetch the cell bounds for the widget.
	            var config = GridLayout.getCellConfig(item.widget);
	            var r1 = Math.min(config.row, maxRow);
	            var c1 = Math.min(config.column, maxCol);
	            var r2 = Math.min(config.row + config.rowSpan - 1, maxRow);
	            var c2 = Math.min(config.column + config.columnSpan - 1, maxCol);
	            // Compute the cell geometry.
	            var x = this._columnStarts[c1];
	            var y = this._rowStarts[r1];
	            var w = this._columnStarts[c2] + this._columnSizers[c2].size - x;
	            var h = this._rowStarts[r2] + this._rowSizers[r2].size - y;
	            // Update the geometry of the layout item.
	            item.update(x, y, w, h);
	        }
	    };
	    return GridLayout;
	}(layout_1.Layout));
	exports.GridLayout = GridLayout;
	/**
	 * The namespace for the `GridLayout` class statics.
	 */
	(function (GridLayout) {
	    /**
	     * Get the cell config for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The cell config for the widget.
	     */
	    function getCellConfig(widget) {
	        return Private.cellConfigProperty.get(widget);
	    }
	    GridLayout.getCellConfig = getCellConfig;
	    /**
	     * Set the cell config for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the cell config.
	     */
	    function setCellConfig(widget, value) {
	        Private.cellConfigProperty.set(widget, Private.normalizeConfig(value));
	    }
	    GridLayout.setCellConfig = setCellConfig;
	})(GridLayout = exports.GridLayout || (exports.GridLayout = {}));
	exports.GridLayout = GridLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The property descriptor for the widget cell config.
	     */
	    Private.cellConfigProperty = new properties_1.AttachedProperty({
	        name: 'cellConfig',
	        create: function () { return ({ row: 0, column: 0, rowSpan: 1, columnSpan: 1 }); },
	        changed: onChildCellConfigChanged
	    });
	    /**
	     * Normalize a partial cell config object.
	     */
	    function normalizeConfig(config) {
	        var row = Math.max(0, Math.floor(config.row || 0));
	        var column = Math.max(0, Math.floor(config.column || 0));
	        var rowSpan = Math.max(1, Math.floor(config.rowSpan || 0));
	        var columnSpan = Math.max(1, Math.floor(config.columnSpan || 0));
	        return { row: row, column: column, rowSpan: rowSpan, columnSpan: columnSpan };
	    }
	    Private.normalizeConfig = normalizeConfig;
	    /**
	     * Clamp a value to an integer >= 0.
	     */
	    function clampValue(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampValue = clampValue;
	    /**
	     * A sort comparison function for row spans.
	     */
	    function rowSpanCmp(a, b) {
	        var c1 = Private.cellConfigProperty.get(a.widget);
	        var c2 = Private.cellConfigProperty.get(b.widget);
	        return c1.rowSpan - c2.rowSpan;
	    }
	    Private.rowSpanCmp = rowSpanCmp;
	    /**
	     * A sort comparison function for column spans.
	     */
	    function columnSpanCmp(a, b) {
	        var c1 = Private.cellConfigProperty.get(a.widget);
	        var c2 = Private.cellConfigProperty.get(b.widget);
	        return c1.columnSpan - c2.columnSpan;
	    }
	    Private.columnSpanCmp = columnSpanCmp;
	    /**
	     * Reallocate the box sizers for the given grid dimensions.
	     */
	    function reallocSizers(sizers, count) {
	        // Coerce the count to the valid range.
	        count = Math.max(1, Math.floor(count));
	        // Add the missing sizers.
	        while (sizers.length < count) {
	            sizers.push(new boxengine_1.BoxSizer());
	        }
	        // Remove the extra sizers.
	        if (sizers.length < count) {
	            sizers.length = count;
	        }
	    }
	    Private.reallocSizers = reallocSizers;
	    /**
	     * Distribute a min size constraint across a range of sizers.
	     */
	    function distributeMin(sizers, i1, i2, minSize) {
	        // Sanity check the indices.
	        if (i2 < i1) {
	            return;
	        }
	        // Handle the simple case of no cell span.
	        if (i1 === i2) {
	            var sizer = sizers[i1];
	            sizer.minSize = Math.max(sizer.minSize, minSize);
	            return;
	        }
	        // Compute the total current min size of the span.
	        var totalMin = 0;
	        for (var i = i1; i <= i2; ++i) {
	            totalMin += sizers[i].minSize;
	        }
	        // Do nothing if the total is greater than the required.
	        if (totalMin >= minSize) {
	            return;
	        }
	        // Compute the portion of the space to allocate to each sizer.
	        var portion = (minSize - totalMin) / (i2 - i1 + 1);
	        // Add the portion to each sizer.
	        for (var i = i1; i <= i2; ++i) {
	            sizers[i].minSize += portion;
	        }
	    }
	    Private.distributeMin = distributeMin;
	    /**
	     * The change handler for the child cell config property.
	     */
	    function onChildCellConfigChanged(child) {
	        if (child.parent && child.parent.layout instanceof GridLayout) {
	            child.parent.fit();
	        }
	    }
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var keyboard_1 = __webpack_require__(210);
	var messaging_1 = __webpack_require__(196);
	var virtualdom_1 = __webpack_require__(211);
	var widget_1 = __webpack_require__(202);
	/**
	 * A widget which displays menus as a canonical menu bar.
	 */
	var MenuBar = (function (_super) {
	    __extends(MenuBar, _super);
	    /**
	     * Construct a new menu bar.
	     *
	     * @param options - The options for initializing the menu bar.
	     */
	    function MenuBar(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._activeIndex = -1;
	        _this._menus = [];
	        _this._childMenu = null;
	        _this.addClass('p-MenuBar');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.renderer = options.renderer || MenuBar.defaultRenderer;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    MenuBar.prototype.dispose = function () {
	        this._closeChildMenu();
	        this._menus.length = 0;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(MenuBar.prototype, "childMenu", {
	        /**
	         * The child menu of the menu bar.
	         *
	         * #### Notes
	         * This will be `null` if the menu bar does not have an open menu.
	         */
	        get: function () {
	            return this._childMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "contentNode", {
	        /**
	         * Get the menu bar content node.
	         *
	         * #### Notes
	         * This is the node which holds the menu title nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-MenuBar-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "activeMenu", {
	        /**
	         * Get the currently active menu.
	         */
	        get: function () {
	            return this._menus[this._activeIndex] || null;
	        },
	        /**
	         * Set the currently active menu.
	         *
	         * #### Notes
	         * If the menu does not exist, the menu will be set to `null`.
	         */
	        set: function (value) {
	            this.activeIndex = value ? this._menus.indexOf(value) : -1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "activeIndex", {
	        /**
	         * Get the index of the currently active menu.
	         *
	         * #### Notes
	         * This will be `-1` if no menu is active.
	         */
	        get: function () {
	            return this._activeIndex;
	        },
	        /**
	         * Set the index of the currently active menu.
	         *
	         * #### Notes
	         * If the menu cannot be activated, the index will be set to `-1`.
	         */
	        set: function (value) {
	            // Adjust the value for an out of range index.
	            if (value < 0 || value >= this._menus.length) {
	                value = -1;
	            }
	            // Bail early if the index will not change.
	            if (this._activeIndex === value) {
	                return;
	            }
	            // Update the active index.
	            this._activeIndex = value;
	            // Schedule an update of the items.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "menus", {
	        /**
	         * A read-only array of the menus in the menu bar.
	         */
	        get: function () {
	            return this._menus;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Open the active menu and activate its first menu item.
	     *
	     * #### Notes
	     * If there is no active menu, this is a no-op.
	     */
	    MenuBar.prototype.openActiveMenu = function () {
	        // Bail early if there is no active item.
	        if (this._activeIndex === -1) {
	            return;
	        }
	        // Open the child menu.
	        this._openChildMenu();
	        // Activate the first item in the child menu.
	        if (this._childMenu) {
	            this._childMenu.activeIndex = -1;
	            this._childMenu.activateNextItem();
	        }
	    };
	    /**
	     * Add a menu to the end of the menu bar.
	     *
	     * @param menu - The menu to add to the menu bar.
	     *
	     * #### Notes
	     * If the menu is already added to the menu bar, it will be moved.
	     */
	    MenuBar.prototype.addMenu = function (menu) {
	        this.insertMenu(this._menus.length, menu);
	    };
	    /**
	     * Insert a menu into the menu bar at the specified index.
	     *
	     * @param index - The index at which to insert the menu.
	     *
	     * @param menu - The menu to insert into the menu bar.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the menus.
	     *
	     * If the menu is already added to the menu bar, it will be moved.
	     */
	    MenuBar.prototype.insertMenu = function (index, menu) {
	        // Close the child menu before making changes.
	        this._closeChildMenu();
	        // Look up the index of the menu.
	        var i = this._menus.indexOf(menu);
	        // Clamp the insert index to the array bounds.
	        var j = Math.max(0, Math.min(index, this._menus.length));
	        // If the menu is not in the array, insert it.
	        if (i === -1) {
	            // Insert the menu into the array.
	            algorithm_1.ArrayExt.insert(this._menus, j, menu);
	            // Add the styling class to the menu.
	            menu.addClass('p-MenuBar-menu');
	            // Connect to the menu signals.
	            menu.aboutToClose.connect(this._onMenuAboutToClose, this);
	            menu.menuRequested.connect(this._onMenuMenuRequested, this);
	            menu.title.changed.connect(this._onTitleChanged, this);
	            // Schedule an update of the items.
	            this.update();
	            // There is nothing more to do.
	            return;
	        }
	        // Otherwise, the menu exists in the array and should be moved.
	        // Adjust the index if the location is at the end of the array.
	        if (j === this._menus.length) {
	            j--;
	        }
	        // Bail if there is no effective move.
	        if (i === j) {
	            return;
	        }
	        // Move the menu to the new locations.
	        algorithm_1.ArrayExt.move(this._menus, i, j);
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Remove a menu from the menu bar.
	     *
	     * @param menu - The menu to remove from the menu bar.
	     *
	     * #### Notes
	     * This is a no-op if the menu is not in the menu bar.
	     */
	    MenuBar.prototype.removeMenu = function (menu) {
	        this.removeMenuAt(this._menus.indexOf(menu));
	    };
	    /**
	     * Remove the menu at a given index from the menu bar.
	     *
	     * @param index - The index of the menu to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    MenuBar.prototype.removeMenuAt = function (index) {
	        // Close the child menu before making changes.
	        this._closeChildMenu();
	        // Remove the menu from the array.
	        var menu = algorithm_1.ArrayExt.removeAt(this._menus, index);
	        // Bail if the index is out of range.
	        if (!menu) {
	            return;
	        }
	        // Disconnect from the menu signals.
	        menu.aboutToClose.disconnect(this._onMenuAboutToClose, this);
	        menu.menuRequested.disconnect(this._onMenuMenuRequested, this);
	        menu.title.changed.disconnect(this._onTitleChanged, this);
	        // Remove the styling class from the menu.
	        menu.removeClass('p-MenuBar-menu');
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Remove all menus from the menu bar.
	     */
	    MenuBar.prototype.clearMenus = function () {
	        // Bail if there is nothing to remove.
	        if (this._menus.length === 0) {
	            return;
	        }
	        // Close the child menu before making changes.
	        this._closeChildMenu();
	        // Disconnect from the menu signals and remove the styling class.
	        for (var _i = 0, _a = this._menus; _i < _a.length; _i++) {
	            var menu = _a[_i];
	            menu.aboutToClose.disconnect(this._onMenuAboutToClose, this);
	            menu.menuRequested.disconnect(this._onMenuMenuRequested, this);
	            menu.title.changed.disconnect(this._onTitleChanged, this);
	            menu.removeClass('p-MenuBar-menu');
	        }
	        // Clear the menus array.
	        this._menus.length = 0;
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Handle the DOM events for the menu bar.
	     *
	     * @param event - The DOM event sent to the menu bar.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the menu bar's DOM nodes. It
	     * should not be called directly by user code.
	     */
	    MenuBar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseleave':
	                this._evtMouseLeave(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    MenuBar.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('keydown', this);
	        this.node.addEventListener('mousedown', this);
	        this.node.addEventListener('mousemove', this);
	        this.node.addEventListener('mouseleave', this);
	        this.node.addEventListener('contextmenu', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    MenuBar.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('keydown', this);
	        this.node.removeEventListener('mousedown', this);
	        this.node.removeEventListener('mousemove', this);
	        this.node.removeEventListener('mouseleave', this);
	        this.node.removeEventListener('contextmenu', this);
	        this._closeChildMenu();
	    };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     */
	    MenuBar.prototype.onActivateRequest = function (msg) {
	        if (this.isAttached) {
	            this.node.focus();
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    MenuBar.prototype.onUpdateRequest = function (msg) {
	        var menus = this._menus;
	        var renderer = this.renderer;
	        var activeIndex = this._activeIndex;
	        var content = new Array(menus.length);
	        for (var i = 0, n = menus.length; i < n; ++i) {
	            var title = menus[i].title;
	            var active = i === activeIndex;
	            content[i] = renderer.renderItem({ title: title, active: active });
	        }
	        virtualdom_1.VirtualDOM.render(content, this.contentNode);
	    };
	    /**
	     * Handle the `'keydown'` event for the menu bar.
	     */
	    MenuBar.prototype._evtKeyDown = function (event) {
	        // A menu bar handles all keydown events.
	        event.preventDefault();
	        event.stopPropagation();
	        // Fetch the key code for the event.
	        var kc = event.keyCode;
	        // Enter, Up Arrow, Down Arrow
	        if (kc === 13 || kc === 38 || kc === 40) {
	            this.openActiveMenu();
	            return;
	        }
	        // Escape
	        if (kc === 27) {
	            this._closeChildMenu();
	            this.activeIndex = -1;
	            this.node.blur();
	            return;
	        }
	        // Left Arrow
	        if (kc === 37) {
	            var i = this._activeIndex;
	            var n = this._menus.length;
	            this.activeIndex = i === 0 ? n - 1 : i - 1;
	            return;
	        }
	        // Right Arrow
	        if (kc === 39) {
	            var i = this._activeIndex;
	            var n = this._menus.length;
	            this.activeIndex = i === n - 1 ? 0 : i + 1;
	            return;
	        }
	        // Get the pressed key character.
	        var key = keyboard_1.getKeyboardLayout().keyForKeydownEvent(event);
	        // Bail if the key is not valid.
	        if (!key) {
	            return;
	        }
	        // Search for the next best matching mnemonic item.
	        var start = this._activeIndex + 1;
	        var result = Private.findMnemonic(this._menus, key, start);
	        // Handle the requested mnemonic based on the search results.
	        // If exactly one mnemonic is matched, that menu is opened.
	        // Otherwise, the next mnemonic is activated if available,
	        // followed by the auto mnemonic if available.
	        if (result.index !== -1 && !result.multiple) {
	            this.activeIndex = result.index;
	            this.openActiveMenu();
	        }
	        else if (result.index !== -1) {
	            this.activeIndex = result.index;
	        }
	        else if (result.auto !== -1) {
	            this.activeIndex = result.auto;
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseDown = function (event) {
	        // Bail if the mouse press was not on the menu bar. This can occur
	        // when the document listener is installed for an active menu bar.
	        if (!domutils_1.ElementExt.hitTest(this.node, event.clientX, event.clientY)) {
	            return;
	        }
	        // Stop the propagation of the event. Immediate propagation is
	        // also stopped so that an open menu does not handle the event.
	        event.preventDefault();
	        event.stopPropagation();
	        event.stopImmediatePropagation();
	        // Check if the mouse is over one of the menu items.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return domutils_1.ElementExt.hitTest(node, event.clientX, event.clientY);
	        });
	        // If the press was not on an item, close the child menu.
	        if (index === -1) {
	            this._closeChildMenu();
	            return;
	        }
	        // If the press was not the left mouse button, do nothing further.
	        if (event.button !== 0) {
	            return;
	        }
	        // Otherwise, toggle the open state of the child menu.
	        if (this._childMenu) {
	            this._closeChildMenu();
	            this.activeIndex = index;
	        }
	        else {
	            this.activeIndex = index;
	            this._openChildMenu();
	        }
	    };
	    /**
	     * Handle the `'mousemove'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseMove = function (event) {
	        // Check if the mouse is over one of the menu items.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return domutils_1.ElementExt.hitTest(node, event.clientX, event.clientY);
	        });
	        // Bail early if the active index will not change.
	        if (index === this._activeIndex) {
	            return;
	        }
	        // Bail early if a child menu is open and the mouse is not over
	        // an item. This allows the child menu to be kept open when the
	        // mouse is over the empty part of the menu bar.
	        if (index === -1 && this._childMenu) {
	            return;
	        }
	        // Update the active index to the hovered item.
	        this.activeIndex = index;
	        // Open the new menu if a menu is already open.
	        if (this._childMenu) {
	            this._openChildMenu();
	        }
	    };
	    /**
	     * Handle the `'mouseleave'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseLeave = function (event) {
	        // Reset the active index if there is no open menu.
	        if (!this._childMenu) {
	            this.activeIndex = -1;
	        }
	    };
	    /**
	     * Open the child menu at the active index immediately.
	     *
	     * If a different child menu is already open, it will be closed,
	     * even if there is no active menu.
	     */
	    MenuBar.prototype._openChildMenu = function () {
	        // If there is no active menu, close the current menu.
	        var newMenu = this.activeMenu;
	        if (!newMenu) {
	            this._closeChildMenu();
	            return;
	        }
	        // Bail if there is no effective menu change.
	        var oldMenu = this._childMenu;
	        if (oldMenu === newMenu) {
	            return;
	        }
	        // Swap the internal menu reference.
	        this._childMenu = newMenu;
	        // Close the current menu, or setup for the new menu.
	        if (oldMenu) {
	            oldMenu.close();
	        }
	        else {
	            this.addClass('p-mod-active');
	            document.addEventListener('mousedown', this, true);
	        }
	        // Ensure the menu bar is updated and look up the item node.
	        messaging_1.MessageLoop.sendMessage(this, widget_1.Widget.Msg.UpdateRequest);
	        var itemNode = this.contentNode.children[this._activeIndex];
	        // Get the positioning data for the new menu.
	        var _a = itemNode.getBoundingClientRect(), left = _a.left, bottom = _a.bottom;
	        // Open the new menu at the computed location.
	        newMenu.open(left, bottom, { forceX: true, forceY: true });
	    };
	    /**
	     * Close the child menu immediately.
	     *
	     * This is a no-op if a child menu is not open.
	     */
	    MenuBar.prototype._closeChildMenu = function () {
	        // Bail if no child menu is open.
	        if (!this._childMenu) {
	            return;
	        }
	        // Remove the active class from the menu bar.
	        this.removeClass('p-mod-active');
	        // Remove the document listeners.
	        document.removeEventListener('mousedown', this, true);
	        // Clear the internal menu reference.
	        var menu = this._childMenu;
	        this._childMenu = null;
	        // Close the menu.
	        menu.close();
	        // Reset the active index.
	        this.activeIndex = -1;
	    };
	    /**
	     * Handle the `aboutToClose` signal of a menu.
	     */
	    MenuBar.prototype._onMenuAboutToClose = function (sender) {
	        // Bail if the sender is not the child menu.
	        if (sender !== this._childMenu) {
	            return;
	        }
	        // Remove the active class from the menu bar.
	        this.removeClass('p-mod-active');
	        // Remove the document listeners.
	        document.removeEventListener('mousedown', this, true);
	        // Clear the internal menu reference.
	        this._childMenu = null;
	        // Reset the active index.
	        this.activeIndex = -1;
	    };
	    /**
	     * Handle the `menuRequested` signal of a child menu.
	     */
	    MenuBar.prototype._onMenuMenuRequested = function (sender, args) {
	        // Bail if the sender is not the child menu.
	        if (sender !== this._childMenu) {
	            return;
	        }
	        // Look up the active index and menu count.
	        var i = this._activeIndex;
	        var n = this._menus.length;
	        // Active the next requested index.
	        switch (args) {
	            case 'next':
	                this.activeIndex = i === n - 1 ? 0 : i + 1;
	                break;
	            case 'previous':
	                this.activeIndex = i === 0 ? n - 1 : i - 1;
	                break;
	        }
	        // Open the active menu.
	        this.openActiveMenu();
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    MenuBar.prototype._onTitleChanged = function () {
	        this.update();
	    };
	    return MenuBar;
	}(widget_1.Widget));
	exports.MenuBar = MenuBar;
	/**
	 * The namespace for the `MenuBar` class statics.
	 */
	(function (MenuBar) {
	    /**
	     * The default implementation of `IRenderer`.
	     *
	     * #### Notes
	     * Subclasses are free to reimplement rendering methods as needed.
	     */
	    var Renderer = (function () {
	        /**
	         * Construct a new renderer.
	         */
	        function Renderer() {
	        }
	        /**
	         * Render the virtual element for a menu bar item.
	         *
	         * @param data - The data to use for rendering the item.
	         *
	         * @returns A virtual element representing the item.
	         */
	        Renderer.prototype.renderItem = function (data) {
	            var className = this.createItemClass(data);
	            var dataset = this.createItemDataset(data);
	            return (virtualdom_1.h.li({ className: className, dataset: dataset }, this.renderIcon(data), this.renderLabel(data)));
	        };
	        /**
	         * Render the icon element for a menu bar item.
	         *
	         * @param data - The data to use for rendering the icon.
	         *
	         * @returns A virtual element representing the item icon.
	         */
	        Renderer.prototype.renderIcon = function (data) {
	            var className = this.createIconClass(data);
	            return virtualdom_1.h.div({ className: className }, data.title.iconLabel);
	        };
	        /**
	         * Render the label element for a menu item.
	         *
	         * @param data - The data to use for rendering the label.
	         *
	         * @returns A virtual element representing the item label.
	         */
	        Renderer.prototype.renderLabel = function (data) {
	            var content = this.formatLabel(data);
	            return virtualdom_1.h.div({ className: 'p-MenuBar-itemLabel' }, content);
	        };
	        /**
	         * Create the class name for the menu bar item.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the menu item.
	         */
	        Renderer.prototype.createItemClass = function (data) {
	            var name = 'p-MenuBar-item';
	            if (data.title.className) {
	                name += " " + data.title.className;
	            }
	            if (data.active) {
	                name += ' p-mod-active';
	            }
	            return name;
	        };
	        /**
	         * Create the dataset for a menu bar item.
	         *
	         * @param data - The data to use for the item.
	         *
	         * @returns The dataset for the menu bar item.
	         */
	        Renderer.prototype.createItemDataset = function (data) {
	            return data.title.dataset;
	        };
	        /**
	         * Create the class name for the menu bar item icon.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the item icon.
	         */
	        Renderer.prototype.createIconClass = function (data) {
	            var name = 'p-MenuBar-itemIcon';
	            var extra = data.title.iconClass;
	            return extra ? name + " " + extra : name;
	        };
	        /**
	         * Create the render content for the label node.
	         *
	         * @param data - The data to use for the label content.
	         *
	         * @returns The content to add to the label node.
	         */
	        Renderer.prototype.formatLabel = function (data) {
	            // Fetch the label text and mnemonic index.
	            var _a = data.title, label = _a.label, mnemonic = _a.mnemonic;
	            // If the index is out of range, do not modify the label.
	            if (mnemonic < 0 || mnemonic >= label.length) {
	                return label;
	            }
	            // Split the label into parts.
	            var prefix = label.slice(0, mnemonic);
	            var suffix = label.slice(mnemonic + 1);
	            var char = label[mnemonic];
	            // Wrap the mnemonic character in a span.
	            var span = virtualdom_1.h.span({ className: 'p-MenuBar-itemMnemonic' }, char);
	            // Return the content parts.
	            return [prefix, span, suffix];
	        };
	        return Renderer;
	    }());
	    MenuBar.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    MenuBar.defaultRenderer = new Renderer();
	})(MenuBar = exports.MenuBar || (exports.MenuBar = {}));
	exports.MenuBar = MenuBar;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the DOM node for a menu bar.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = 'p-MenuBar-content';
	        node.appendChild(content);
	        node.tabIndex = -1;
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Find the best matching mnemonic item.
	     *
	     * The search starts at the given index and wraps around.
	     */
	    function findMnemonic(menus, key, start) {
	        // Setup the result variables.
	        var index = -1;
	        var auto = -1;
	        var multiple = false;
	        // Normalize the key to upper case.
	        var upperKey = key.toUpperCase();
	        // Search the items from the given start index.
	        for (var i = 0, n = menus.length; i < n; ++i) {
	            // Compute the wrapped index.
	            var k = (i + start) % n;
	            // Look up the menu title.
	            var title = menus[k].title;
	            // Ignore titles with an empty label.
	            if (title.label.length === 0) {
	                continue;
	            }
	            // Look up the mnemonic index for the label.
	            var mn = title.mnemonic;
	            // Handle a valid mnemonic index.
	            if (mn >= 0 && mn < title.label.length) {
	                if (title.label[mn].toUpperCase() === upperKey) {
	                    if (index === -1) {
	                        index = k;
	                    }
	                    else {
	                        multiple = true;
	                    }
	                }
	                continue;
	            }
	            // Finally, handle the auto index if possible.
	            if (auto === -1 && title.label[0].toUpperCase() === upperKey) {
	                auto = k;
	            }
	        }
	        // Return the search results.
	        return { index: index, multiple: multiple, auto: auto };
	    }
	    Private.findMnemonic = findMnemonic;
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var domutils_1 = __webpack_require__(192);
	var dragdrop_1 = __webpack_require__(216);
	var signaling_1 = __webpack_require__(201);
	var widget_1 = __webpack_require__(202);
	/**
	 * A widget which implements a canonical scroll bar.
	 */
	var ScrollBar = (function (_super) {
	    __extends(ScrollBar, _super);
	    /**
	     * Construct a new scroll bar.
	     *
	     * @param options - The options for initializing the scroll bar.
	     */
	    function ScrollBar(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        /**
	         * A timeout callback for repeating the mouse press.
	         */
	        _this._onRepeat = function () {
	            // Clear the repeat timer id.
	            _this._repeatTimer = -1;
	            // Bail if the mouse has been released.
	            if (!_this._pressData) {
	                return;
	            }
	            // Look up the part that was pressed.
	            var part = _this._pressData.part;
	            // Bail if the thumb was pressed.
	            if (part === 'thumb') {
	                return;
	            }
	            // Schedule the timer for another repeat.
	            _this._repeatTimer = setTimeout(_this._onRepeat, 20);
	            // Get the current mouse position.
	            var mouseX = _this._pressData.mouseX;
	            var mouseY = _this._pressData.mouseY;
	            // Handle a decrement button repeat.
	            if (part === 'decrement') {
	                // Bail if the mouse is not over the button.
	                if (!domutils_1.ElementExt.hitTest(_this.decrementNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Emit the step requested signal.
	                _this._stepRequested.emit('decrement');
	                // Finished.
	                return;
	            }
	            // Handle an increment button repeat.
	            if (part === 'increment') {
	                // Bail if the mouse is not over the button.
	                if (!domutils_1.ElementExt.hitTest(_this.incrementNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Emit the step requested signal.
	                _this._stepRequested.emit('increment');
	                // Finished.
	                return;
	            }
	            // Handle a track repeat.
	            if (part === 'track') {
	                // Bail if the mouse is not over the track.
	                if (!domutils_1.ElementExt.hitTest(_this.trackNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Fetch the thumb node.
	                var thumbNode = _this.thumbNode;
	                // Bail if the mouse is over the thumb.
	                if (domutils_1.ElementExt.hitTest(thumbNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Fetch the client rect for the thumb.
	                var thumbRect = thumbNode.getBoundingClientRect();
	                // Determine the direction for the page request.
	                var dir = void 0;
	                if (_this._orientation === 'horizontal') {
	                    dir = mouseX < thumbRect.left ? 'decrement' : 'increment';
	                }
	                else {
	                    dir = mouseY < thumbRect.top ? 'decrement' : 'increment';
	                }
	                // Emit the page requested signal.
	                _this._pageRequested.emit(dir);
	                // Finished.
	                return;
	            }
	        };
	        _this._value = 0;
	        _this._page = 10;
	        _this._maximum = 100;
	        _this._repeatTimer = -1;
	        _this._pressData = null;
	        _this._thumbMoved = new signaling_1.Signal(_this);
	        _this._stepRequested = new signaling_1.Signal(_this);
	        _this._pageRequested = new signaling_1.Signal(_this);
	        _this.addClass('p-ScrollBar');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        // Set the orientation.
	        _this._orientation = options.orientation || 'vertical';
	        _this.dataset['orientation'] = _this._orientation;
	        // Parse the rest of the options.
	        if (options.maximum !== undefined) {
	            _this._maximum = Math.max(0, options.maximum);
	        }
	        if (options.page !== undefined) {
	            _this._page = Math.max(0, options.page);
	        }
	        if (options.value !== undefined) {
	            _this._value = Math.max(0, Math.min(options.value, _this._maximum));
	        }
	        return _this;
	    }
	    Object.defineProperty(ScrollBar.prototype, "thumbMoved", {
	        /**
	         * A signal emitted when the user moves the scroll thumb.
	         *
	         * #### Notes
	         * The payload is the current value of the scroll bar.
	         */
	        get: function () {
	            return this._thumbMoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "stepRequested", {
	        /**
	         * A signal emitted when the user clicks a step button.
	         *
	         * #### Notes
	         * The payload is whether a decrease or increase is requested.
	         */
	        get: function () {
	            return this._stepRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "pageRequested", {
	        /**
	         * A signal emitted when the user clicks the scroll track.
	         *
	         * #### Notes
	         * The payload is whether a decrease or increase is requested.
	         */
	        get: function () {
	            return this._pageRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "orientation", {
	        /**
	         * Get the orientation of the scroll bar.
	         */
	        get: function () {
	            return this._orientation;
	        },
	        /**
	         * Set the orientation of the scroll bar.
	         */
	        set: function (value) {
	            // Do nothing if the orientation does not change.
	            if (this._orientation === value) {
	                return;
	            }
	            // Release the mouse before making changes.
	            this._releaseMouse();
	            // Update the internal orientation.
	            this._orientation = value;
	            this.dataset['orientation'] = value;
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "value", {
	        /**
	         * Get the current value of the scroll bar.
	         */
	        get: function () {
	            return this._value;
	        },
	        /**
	         * Set the current value of the scroll bar.
	         *
	         * #### Notes
	         * The value will be clamped to the range `[0, maximum]`.
	         */
	        set: function (value) {
	            // Clamp the value to the allowable range.
	            value = Math.max(0, Math.min(value, this._maximum));
	            // Do nothing if the value does not change.
	            if (this._value === value) {
	                return;
	            }
	            // Update the internal value.
	            this._value = value;
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "page", {
	        /**
	         * Get the page size of the scroll bar.
	         *
	         * #### Notes
	         * The page size is the amount of visible content in the scrolled
	         * region, expressed in data units. It determines the size of the
	         * scroll bar thumb.
	         */
	        get: function () {
	            return this._page;
	        },
	        /**
	         * Set the page size of the scroll bar.
	         *
	         * #### Notes
	         * The page size will be clamped to the range `[0, Infinity]`.
	         */
	        set: function (value) {
	            // Clamp the page size to the allowable range.
	            value = Math.max(0, value);
	            // Do nothing if the value does not change.
	            if (this._page === value) {
	                return;
	            }
	            // Update the internal page size.
	            this._page = value;
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "maximum", {
	        /**
	         * Get the maximum value of the scroll bar.
	         */
	        get: function () {
	            return this._maximum;
	        },
	        /**
	         * Set the maximum value of the scroll bar.
	         *
	         * #### Notes
	         * The max size will be clamped to the range `[0, Infinity]`.
	         */
	        set: function (value) {
	            // Clamp the value to the allowable range.
	            value = Math.max(0, value);
	            // Do nothing if the value does not change.
	            if (this._maximum === value) {
	                return;
	            }
	            // Update the internal values.
	            this._maximum = value;
	            // Clamp the current value to the new range.
	            this._value = Math.min(this._value, value);
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "decrementNode", {
	        /**
	         * The scroll bar decrement button node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-button')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "incrementNode", {
	        /**
	         * The scroll bar increment button node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-button')[1];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "trackNode", {
	        /**
	         * The scroll bar track node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-track')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "thumbNode", {
	        /**
	         * The scroll bar thumb node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-thumb')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Handle the DOM events for the scroll bar.
	     *
	     * @param event - The DOM event sent to the scroll bar.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the scroll bar's DOM node.
	     *
	     * This should not be called directly by user code.
	     */
	    ScrollBar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A method invoked on a 'before-attach' message.
	     */
	    ScrollBar.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	        this.update();
	    };
	    /**
	     * A method invoked on an 'after-detach' message.
	     */
	    ScrollBar.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A method invoked on an 'update-request' message.
	     */
	    ScrollBar.prototype.onUpdateRequest = function (msg) {
	        // Convert the value and page into percentages.
	        var value = this._value * 100 / this._maximum;
	        var page = this._page * 100 / (this._page + this._maximum);
	        // Clamp the value and page to the relevant range.
	        value = Math.max(0, Math.min(value, 100));
	        page = Math.max(0, Math.min(page, 100));
	        // Fetch the thumb style.
	        var thumbStyle = this.thumbNode.style;
	        // Update the thumb style for the current orientation.
	        if (this._orientation === 'horizontal') {
	            thumbStyle.top = '';
	            thumbStyle.height = '';
	            thumbStyle.left = value + "%";
	            thumbStyle.width = page + "%";
	            thumbStyle.transform = "translate(" + -value + "%, 0%)";
	        }
	        else {
	            thumbStyle.left = '';
	            thumbStyle.width = '';
	            thumbStyle.top = value + "%";
	            thumbStyle.height = page + "%";
	            thumbStyle.transform = "translate(0%, " + -value + "%)";
	        }
	    };
	    /**
	     * Handle the `'keydown'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtKeyDown = function (event) {
	        // Stop all input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Ignore anything except the `Escape` key.
	        if (event.keyCode !== 27) {
	            return;
	        }
	        // Fetch the previous scroll value.
	        var value = this._pressData ? this._pressData.value : -1;
	        // Release the mouse.
	        this._releaseMouse();
	        // Restore the old scroll value if possible.
	        if (value !== -1) {
	            this._moveThumb(value);
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtMouseDown = function (event) {
	        // Do nothing if it's not a left mouse press.
	        if (event.button !== 0) {
	            return;
	        }
	        // Do nothing if the mouse is already captured.
	        if (this._pressData) {
	            return;
	        }
	        // Find the pressed scroll bar part.
	        var part = Private.findPart(this, event.target);
	        // Do nothing if the part is not of interest.
	        if (!part) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Override the mouse cursor.
	        var override = dragdrop_1.Drag.overrideCursor('default');
	        // Set up the press data.
	        this._pressData = {
	            part: part, override: override,
	            delta: -1, value: -1,
	            mouseX: event.clientX,
	            mouseY: event.clientY
	        };
	        // Add the extra event listeners.
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('contextmenu', this, true);
	        // Handle a thumb press.
	        if (part === 'thumb') {
	            // Fetch the thumb node.
	            var thumbNode = this.thumbNode;
	            // Fetch the client rect for the thumb.
	            var thumbRect = thumbNode.getBoundingClientRect();
	            // Update the press data delta for the current orientation.
	            if (this._orientation === 'horizontal') {
	                this._pressData.delta = event.clientX - thumbRect.left;
	            }
	            else {
	                this._pressData.delta = event.clientY - thumbRect.top;
	            }
	            // Add the active class to the thumb node.
	            thumbNode.classList.add('p-mod-active');
	            // Store the current value in the press data.
	            this._pressData.value = this._value;
	            // Finished.
	            return;
	        }
	        // Handle a track press.
	        if (part === 'track') {
	            // Fetch the client rect for the thumb.
	            var thumbRect = this.thumbNode.getBoundingClientRect();
	            // Determine the direction for the page request.
	            var dir = void 0;
	            if (this._orientation === 'horizontal') {
	                dir = event.clientX < thumbRect.left ? 'decrement' : 'increment';
	            }
	            else {
	                dir = event.clientY < thumbRect.top ? 'decrement' : 'increment';
	            }
	            // Start the repeat timer.
	            this._repeatTimer = setTimeout(this._onRepeat, 350);
	            // Emit the page requested signal.
	            this._pageRequested.emit(dir);
	            // Finished.
	            return;
	        }
	        // Handle a decrement button press.
	        if (part === 'decrement') {
	            // Add the active class to the decrement node.
	            this.decrementNode.classList.add('p-mod-active');
	            // Start the repeat timer.
	            this._repeatTimer = setTimeout(this._onRepeat, 350);
	            // Emit the step requested signal.
	            this._stepRequested.emit('decrement');
	            // Finished.
	            return;
	        }
	        // Handle an increment button press.
	        if (part === 'increment') {
	            // Add the active class to the increment node.
	            this.incrementNode.classList.add('p-mod-active');
	            // Start the repeat timer.
	            this._repeatTimer = setTimeout(this._onRepeat, 350);
	            // Emit the step requested signal.
	            this._stepRequested.emit('increment');
	            // Finished.
	            return;
	        }
	    };
	    /**
	     * Handle the `'mousemove'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtMouseMove = function (event) {
	        // Do nothing if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Update the mouse position.
	        this._pressData.mouseX = event.clientX;
	        this._pressData.mouseY = event.clientY;
	        // Bail if the thumb is not being dragged.
	        if (this._pressData.part !== 'thumb') {
	            return;
	        }
	        // Get the client rect for the thumb and track.
	        var thumbRect = this.thumbNode.getBoundingClientRect();
	        var trackRect = this.trackNode.getBoundingClientRect();
	        // Fetch the scroll geometry based on the orientation.
	        var trackPos;
	        var trackSpan;
	        if (this._orientation === 'horizontal') {
	            trackPos = event.clientX - trackRect.left - this._pressData.delta;
	            trackSpan = trackRect.width - thumbRect.width;
	        }
	        else {
	            trackPos = event.clientY - trackRect.top - this._pressData.delta;
	            trackSpan = trackRect.height - thumbRect.height;
	        }
	        // Compute the desired value from the scroll geometry.
	        var value = trackSpan === 0 ? 0 : trackPos * this._maximum / trackSpan;
	        // Move the thumb to the computed value.
	        this._moveThumb(value);
	    };
	    /**
	     * Handle the `'mouseup'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtMouseUp = function (event) {
	        // Do nothing if it's not a left mouse release.
	        if (event.button !== 0) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse.
	        this._releaseMouse();
	    };
	    /**
	     * Release the mouse and restore the node states.
	     */
	    ScrollBar.prototype._releaseMouse = function () {
	        // Bail if there is no press data.
	        if (!this._pressData) {
	            return;
	        }
	        // Clear the repeat timer.
	        clearTimeout(this._repeatTimer);
	        this._repeatTimer = -1;
	        // Clear the press data.
	        this._pressData.override.dispose();
	        this._pressData = null;
	        // Remove the extra event listeners.
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	        // Remove the active classes from the nodes.
	        this.thumbNode.classList.remove('p-mod-active');
	        this.decrementNode.classList.remove('p-mod-active');
	        this.incrementNode.classList.remove('p-mod-active');
	    };
	    /**
	     * Move the thumb to the specified position.
	     */
	    ScrollBar.prototype._moveThumb = function (value) {
	        // Clamp the value to the allowed range.
	        value = Math.max(0, Math.min(value, this._maximum));
	        // Bail if the value does not change.
	        if (this._value === value) {
	            return;
	        }
	        // Update the internal value.
	        this._value = value;
	        // Schedule an update of the scroll bar.
	        this.update();
	        // Emit the thumb moved signal.
	        this._thumbMoved.emit(value);
	    };
	    return ScrollBar;
	}(widget_1.Widget));
	exports.ScrollBar = ScrollBar;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the DOM node for a scroll bar.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var decrement = document.createElement('div');
	        var increment = document.createElement('div');
	        var track = document.createElement('div');
	        var thumb = document.createElement('div');
	        decrement.className = 'p-ScrollBar-button';
	        increment.className = 'p-ScrollBar-button';
	        decrement.dataset['action'] = 'decrement';
	        increment.dataset['action'] = 'increment';
	        track.className = 'p-ScrollBar-track';
	        thumb.className = 'p-ScrollBar-thumb';
	        track.appendChild(thumb);
	        node.appendChild(decrement);
	        node.appendChild(track);
	        node.appendChild(increment);
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Find the scroll bar part which contains the given target.
	     */
	    function findPart(scrollBar, target) {
	        // Test the thumb.
	        if (scrollBar.thumbNode.contains(target)) {
	            return 'thumb';
	        }
	        // Test the track.
	        if (scrollBar.trackNode.contains(target)) {
	            return 'track';
	        }
	        // Test the decrement button.
	        if (scrollBar.decrementNode.contains(target)) {
	            return 'decrement';
	        }
	        // Test the increment button.
	        if (scrollBar.incrementNode.contains(target)) {
	            return 'increment';
	        }
	        // Indicate no match.
	        return null;
	    }
	    Private.findPart = findPart;
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var messaging_1 = __webpack_require__(196);
	var properties_1 = __webpack_require__(199);
	var boxengine_1 = __webpack_require__(173);
	var layout_1 = __webpack_require__(200);
	var panellayout_1 = __webpack_require__(204);
	var widget_1 = __webpack_require__(202);
	/**
	 * A layout which arranges its widgets into resizable sections.
	 */
	var SplitLayout = (function (_super) {
	    __extends(SplitLayout, _super);
	    /**
	     * Construct a new split layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function SplitLayout(options) {
	        var _this = _super.call(this) || this;
	        _this._fixed = 0;
	        _this._spacing = 4;
	        _this._dirty = false;
	        _this._hasNormedSizes = false;
	        _this._sizers = [];
	        _this._items = [];
	        _this._handles = [];
	        _this._box = null;
	        _this._alignment = 'start';
	        _this._orientation = 'horizontal';
	        _this.renderer = options.renderer;
	        if (options.orientation !== undefined) {
	            _this._orientation = options.orientation;
	        }
	        if (options.alignment !== undefined) {
	            _this._alignment = options.alignment;
	        }
	        if (options.spacing !== undefined) {
	            _this._spacing = Private.clampSpacing(options.spacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    SplitLayout.prototype.dispose = function () {
	        // Dispose of the layout items.
	        algorithm_1.each(this._items, function (item) { item.dispose(); });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        this._sizers.length = 0;
	        this._handles.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(SplitLayout.prototype, "orientation", {
	        /**
	         * Get the layout orientation for the split layout.
	         */
	        get: function () {
	            return this._orientation;
	        },
	        /**
	         * Set the layout orientation for the split layout.
	         */
	        set: function (value) {
	            if (this._orientation === value) {
	                return;
	            }
	            this._orientation = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['orientation'] = value;
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitLayout.prototype, "alignment", {
	        /**
	         * Get the content alignment for the split layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand  to fill the
	         * entire split layout.
	         */
	        get: function () {
	            return this._alignment;
	        },
	        /**
	         * Set the content alignment for the split layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand  to fill the
	         * entire split layout.
	         */
	        set: function (value) {
	            if (this._alignment === value) {
	                return;
	            }
	            this._alignment = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['alignment'] = value;
	            this.parent.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitLayout.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the split layout.
	         */
	        get: function () {
	            return this._spacing;
	        },
	        /**
	         * Set the inter-element spacing for the split layout.
	         */
	        set: function (value) {
	            value = Private.clampSpacing(value);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitLayout.prototype, "handles", {
	        /**
	         * A read-only array of the split handles in the layout.
	         */
	        get: function () {
	            return this._handles;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the relative sizes of the widgets in the layout.
	     *
	     * @returns A new array of the relative sizes of the widgets.
	     *
	     * #### Notes
	     * The returned sizes reflect the sizes of the widgets normalized
	     * relative to their siblings.
	     *
	     * This method **does not** measure the DOM nodes.
	     */
	    SplitLayout.prototype.relativeSizes = function () {
	        return Private.normalize(this._sizers.map(function (sizer) { return sizer.size; }));
	    };
	    /**
	     * Set the relative sizes for the widgets in the layout.
	     *
	     * @param sizes - The relative sizes for the widgets in the panel.
	     *
	     * #### Notes
	     * Extra values are ignored, too few will yield an undefined layout.
	     *
	     * The actual geometry of the DOM nodes is updated asynchronously.
	     */
	    SplitLayout.prototype.setRelativeSizes = function (sizes) {
	        // Copy the sizes and pad with zeros as needed.
	        var n = this._sizers.length;
	        var temp = sizes.slice(0, n);
	        while (temp.length < n) {
	            temp.push(0);
	        }
	        // Normalize the padded sizes.
	        var normed = Private.normalize(temp);
	        // Apply the normalized sizes to the sizers.
	        for (var i = 0; i < n; ++i) {
	            var sizer = this._sizers[i];
	            sizer.sizeHint = normed[i];
	            sizer.size = normed[i];
	        }
	        // Set the flag indicating the sizes are normalized.
	        this._hasNormedSizes = true;
	        // Trigger an update of the parent widget.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Move the offset position of a split handle.
	     *
	     * @param index - The index of the handle of the interest.
	     *
	     * @param position - The desired offset position of the handle.
	     *
	     * #### Notes
	     * The position is relative to the offset parent.
	     *
	     * This will move the handle as close as possible to the desired
	     * position. The sibling widgets will be adjusted as necessary.
	     */
	    SplitLayout.prototype.moveHandle = function (index, position) {
	        // Bail if the index is invalid or the handle is hidden.
	        var handle = this._handles[index];
	        if (!handle || handle.classList.contains('p-mod-hidden')) {
	            return;
	        }
	        // Compute the desired delta movement for the handle.
	        var delta;
	        if (this._orientation === 'horizontal') {
	            delta = position - handle.offsetLeft;
	        }
	        else {
	            delta = position - handle.offsetTop;
	        }
	        // Bail if there is no handle movement.
	        if (delta === 0) {
	            return;
	        }
	        // Prevent widget resizing unless needed.
	        for (var _i = 0, _a = this._sizers; _i < _a.length; _i++) {
	            var sizer = _a[_i];
	            if (sizer.size > 0) {
	                sizer.sizeHint = sizer.size;
	            }
	        }
	        // Adjust the sizers to reflect the handle movement.
	        boxengine_1.BoxEngine.adjust(this._sizers, index, delta);
	        // Update the layout of the widgets.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    SplitLayout.prototype.init = function () {
	        this.parent.dataset['orientation'] = this.orientation;
	        this.parent.dataset['alignment'] = this.alignment;
	        _super.prototype.init.call(this);
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.attachWidget = function (index, widget) {
	        // Create the item, handle, and sizer for the new widget.
	        var item = new layout_1.LayoutItem(widget);
	        var handle = Private.createHandle(this.renderer);
	        var average = Private.averageSize(this._sizers);
	        var sizer = Private.createSizer(average);
	        // Insert the item, handle, and sizer into the internal arrays.
	        algorithm_1.ArrayExt.insert(this._items, index, item);
	        algorithm_1.ArrayExt.insert(this._sizers, index, sizer);
	        algorithm_1.ArrayExt.insert(this._handles, index, handle);
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget and handle nodes to the parent.
	        this.parent.node.appendChild(widget.node);
	        this.parent.node.appendChild(handle);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Move the item, sizer, and handle for the widget.
	        algorithm_1.ArrayExt.move(this._items, fromIndex, toIndex);
	        algorithm_1.ArrayExt.move(this._sizers, fromIndex, toIndex);
	        algorithm_1.ArrayExt.move(this._handles, fromIndex, toIndex);
	        // Post a fit request to the parent to show/hide last handle.
	        this.parent.fit();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.detachWidget = function (index, widget) {
	        // Remove the item, handle, and sizer for the widget.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        var handle = algorithm_1.ArrayExt.removeAt(this._handles, index);
	        algorithm_1.ArrayExt.removeAt(this._sizers, index);
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget and handle nodes from the parent.
	        this.parent.node.removeChild(widget.node);
	        this.parent.node.removeChild(handle);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Dispose of the layout item.
	        item.dispose();
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    SplitLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    SplitLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    SplitLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    SplitLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    SplitLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    SplitLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    SplitLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    SplitLayout.prototype._fit = function () {
	        // Update the handles and track the visible widget count.
	        var nVisible = 0;
	        var lastHandleIndex = -1;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            if (this._items[i].isHidden) {
	                this._handles[i].classList.add('p-mod-hidden');
	            }
	            else {
	                this._handles[i].classList.remove('p-mod-hidden');
	                lastHandleIndex = i;
	                nVisible++;
	            }
	        }
	        // Hide the handle for the last visible widget.
	        if (lastHandleIndex !== -1) {
	            this._handles[lastHandleIndex].classList.add('p-mod-hidden');
	        }
	        // Update the fixed space for the visible items.
	        this._fixed = this._spacing * Math.max(0, nVisible - 1);
	        // Setup the computed minimum size.
	        var horz = this._orientation === 'horizontal';
	        var minW = horz ? this._fixed : 0;
	        var minH = horz ? 0 : this._fixed;
	        // Update the sizers and computed size limits.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item and corresponding box sizer.
	            var item = this._items[i];
	            var sizer = this._sizers[i];
	            // Prevent resizing unless necessary.
	            if (sizer.size > 0) {
	                sizer.sizeHint = sizer.size;
	            }
	            // If the item is hidden, it should consume zero size.
	            if (item.isHidden) {
	                sizer.minSize = 0;
	                sizer.maxSize = 0;
	                continue;
	            }
	            // Update the size limits for the item.
	            item.fit();
	            // Update the stretch factor.
	            sizer.stretch = SplitLayout.getStretch(item.widget);
	            // Update the sizer limits and computed min size.
	            if (horz) {
	                sizer.minSize = item.minWidth;
	                sizer.maxSize = item.maxWidth;
	                minW += item.minWidth;
	                minH = Math.max(minH, item.minHeight);
	            }
	            else {
	                sizer.minSize = item.minHeight;
	                sizer.maxSize = item.maxHeight;
	                minH += item.minHeight;
	                minW = Math.max(minW, item.minWidth);
	            }
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    SplitLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Bail early if there are no visible items to layout.
	        if (nVisible === 0) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the actual layout bounds adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Compute the adjusted layout space.
	        var space;
	        var horz = this._orientation === 'horizontal';
	        if (horz) {
	            space = Math.max(0, width - this._fixed);
	        }
	        else {
	            space = Math.max(0, height - this._fixed);
	        }
	        // Scale the size hints if they are normalized.
	        if (this._hasNormedSizes) {
	            for (var _i = 0, _a = this._sizers; _i < _a.length; _i++) {
	                var sizer = _a[_i];
	                sizer.sizeHint *= space;
	            }
	            this._hasNormedSizes = false;
	        }
	        // Distribute the layout space to the box sizers.
	        var delta = boxengine_1.BoxEngine.calc(this._sizers, space);
	        // Set up the variables for justification and alignment offset.
	        var extra = 0;
	        var offset = 0;
	        // Account for alignment if there is extra layout space.
	        if (delta > 0) {
	            switch (this._alignment) {
	                case 'start':
	                    break;
	                case 'center':
	                    extra = 0;
	                    offset = delta / 2;
	                    break;
	                case 'end':
	                    extra = 0;
	                    offset = delta;
	                    break;
	                case 'justify':
	                    extra = delta / nVisible;
	                    offset = 0;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Layout the items using the computed box sizes.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Fetch the computed size for the widget.
	            var size = this._sizers[i].size;
	            // Fetch the style for the handle.
	            var handleStyle = this._handles[i].style;
	            // Update the widget and handle, and advance the relevant edge.
	            if (horz) {
	                item.update(left + offset, top, size + extra, height);
	                left += size + extra;
	                handleStyle.top = top + "px";
	                handleStyle.left = left + offset + "px";
	                handleStyle.width = this._spacing + "px";
	                handleStyle.height = height + "px";
	                left += this._spacing;
	            }
	            else {
	                item.update(left, top + offset, width, size + extra);
	                top += size + extra;
	                handleStyle.top = top + offset + "px";
	                handleStyle.left = left + "px";
	                handleStyle.width = width + "px";
	                handleStyle.height = this._spacing + "px";
	                top += this._spacing;
	            }
	        }
	    };
	    return SplitLayout;
	}(panellayout_1.PanelLayout));
	exports.SplitLayout = SplitLayout;
	/**
	 * The namespace for the `SplitLayout` class statics.
	 */
	(function (SplitLayout) {
	    /**
	     * Get the split layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The split layout stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return Private.stretchProperty.get(widget);
	    }
	    SplitLayout.getStretch = getStretch;
	    /**
	     * Set the split layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        Private.stretchProperty.set(widget, value);
	    }
	    SplitLayout.setStretch = setStretch;
	})(SplitLayout = exports.SplitLayout || (exports.SplitLayout = {}));
	exports.SplitLayout = SplitLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The property descriptor for a widget stretch factor.
	     */
	    Private.stretchProperty = new properties_1.AttachedProperty({
	        name: 'stretch',
	        create: function () { return 0; },
	        coerce: function (owner, value) { return Math.max(0, Math.floor(value)); },
	        changed: onChildSizingChanged
	    });
	    /**
	     * Create a new box sizer with the given size hint.
	     */
	    function createSizer(size) {
	        var sizer = new boxengine_1.BoxSizer();
	        sizer.sizeHint = Math.floor(size);
	        return sizer;
	    }
	    Private.createSizer = createSizer;
	    /**
	     * Create a new split handle node using the given renderer.
	     */
	    function createHandle(renderer) {
	        var handle = renderer.createHandle();
	        handle.style.position = 'absolute';
	        return handle;
	    }
	    Private.createHandle = createHandle;
	    /**
	     * Clamp a spacing value to an integer >= 0.
	     */
	    function clampSpacing(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampSpacing = clampSpacing;
	    /**
	     * Compute the average size of an array of box sizers.
	     */
	    function averageSize(sizers) {
	        return sizers.reduce(function (v, s) { return v + s.size; }, 0) / sizers.length || 0;
	    }
	    Private.averageSize = averageSize;
	    /**
	     * Normalize an array of values.
	     */
	    function normalize(values) {
	        var n = values.length;
	        if (n === 0) {
	            return [];
	        }
	        var sum = values.reduce(function (a, b) { return a + Math.abs(b); }, 0);
	        return sum === 0 ? values.map(function (v) { return 1 / n; }) : values.map(function (v) { return v / sum; });
	    }
	    Private.normalize = normalize;
	    /**
	     * The change handler for the attached sizing properties.
	     */
	    function onChildSizingChanged(child) {
	        if (child.parent && child.parent.layout instanceof SplitLayout) {
	            child.parent.fit();
	        }
	    }
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var dragdrop_1 = __webpack_require__(216);
	var panel_1 = __webpack_require__(206);
	var splitlayout_1 = __webpack_require__(222);
	/**
	 * A panel which arranges its widgets into resizable sections.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[SplitLayout]].
	 */
	var SplitPanel = (function (_super) {
	    __extends(SplitPanel, _super);
	    /**
	     * Construct a new split panel.
	     *
	     * @param options - The options for initializing the split panel.
	     */
	    function SplitPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { layout: Private.createLayout(options) }) || this;
	        _this._pressData = null;
	        _this.addClass('p-SplitPanel');
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the panel.
	     */
	    SplitPanel.prototype.dispose = function () {
	        this._releaseMouse();
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(SplitPanel.prototype, "orientation", {
	        /**
	         * Get the layout orientation for the split panel.
	         */
	        get: function () {
	            return this.layout.orientation;
	        },
	        /**
	         * Set the layout orientation for the split panel.
	         */
	        set: function (value) {
	            this.layout.orientation = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "alignment", {
	        /**
	         * Get the content alignment for the split panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire split panel.
	         */
	        get: function () {
	            return this.layout.alignment;
	        },
	        /**
	         * Set the content alignment for the split panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire split panel.
	         */
	        set: function (value) {
	            this.layout.alignment = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the split panel.
	         */
	        get: function () {
	            return this.layout.spacing;
	        },
	        /**
	         * Set the inter-element spacing for the split panel.
	         */
	        set: function (value) {
	            this.layout.spacing = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "renderer", {
	        /**
	         * The renderer used by the split panel.
	         */
	        get: function () {
	            return this.layout.renderer;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "handles", {
	        /**
	         * A read-only array of the split handles in the panel.
	         */
	        get: function () {
	            return this.layout.handles;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the relative sizes of the widgets in the panel.
	     *
	     * @returns A new array of the relative sizes of the widgets.
	     *
	     * #### Notes
	     * The returned sizes reflect the sizes of the widgets normalized
	     * relative to their siblings.
	     *
	     * This method **does not** measure the DOM nodes.
	     */
	    SplitPanel.prototype.relativeSizes = function () {
	        return this.layout.relativeSizes();
	    };
	    /**
	     * Set the relative sizes for the widgets in the panel.
	     *
	     * @param sizes - The relative sizes for the widgets in the panel.
	     *
	     * #### Notes
	     * Extra values are ignored, too few will yield an undefined layout.
	     *
	     * The actual geometry of the DOM nodes is updated asynchronously.
	     */
	    SplitPanel.prototype.setRelativeSizes = function (sizes) {
	        this.layout.setRelativeSizes(sizes);
	    };
	    /**
	     * Handle the DOM events for the split panel.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    SplitPanel.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    SplitPanel.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    SplitPanel.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    SplitPanel.prototype.onChildAdded = function (msg) {
	        msg.child.addClass('p-SplitPanel-child');
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    SplitPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass('p-SplitPanel-child');
	        this._releaseMouse();
	    };
	    /**
	     * Handle the `'keydown'` event for the split panel.
	     */
	    SplitPanel.prototype._evtKeyDown = function (event) {
	        // Stop input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            this._releaseMouse();
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the split panel.
	     */
	    SplitPanel.prototype._evtMouseDown = function (event) {
	        // Do nothing if the left mouse button is not pressed.
	        if (event.button !== 0) {
	            return;
	        }
	        // Find the handle which contains the mouse target, if any.
	        var layout = this.layout;
	        var index = algorithm_1.ArrayExt.findFirstIndex(layout.handles, function (handle) {
	            return handle.contains(event.target);
	        });
	        // Bail early if the mouse press was not on a handle.
	        if (index === -1) {
	            return;
	        }
	        // Stop the event when a split handle is pressed.
	        event.preventDefault();
	        event.stopPropagation();
	        // Add the extra document listeners.
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('contextmenu', this, true);
	        // Compute the offset delta for the handle press.
	        var delta;
	        var handle = layout.handles[index];
	        var rect = handle.getBoundingClientRect();
	        if (layout.orientation === 'horizontal') {
	            delta = event.clientX - rect.left;
	        }
	        else {
	            delta = event.clientY - rect.top;
	        }
	        // Override the cursor and store the press data.
	        var style = window.getComputedStyle(handle);
	        var override = dragdrop_1.Drag.overrideCursor(style.cursor);
	        this._pressData = { index: index, delta: delta, override: override };
	    };
	    /**
	     * Handle the `'mousemove'` event for the split panel.
	     */
	    SplitPanel.prototype._evtMouseMove = function (event) {
	        // Stop the event when dragging a split handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Compute the desired offset position for the handle.
	        var pos;
	        var layout = this.layout;
	        var rect = this.node.getBoundingClientRect();
	        if (layout.orientation === 'horizontal') {
	            pos = event.clientX - rect.left - this._pressData.delta;
	        }
	        else {
	            pos = event.clientY - rect.top - this._pressData.delta;
	        }
	        // Move the handle as close to the desired position as possible.
	        layout.moveHandle(this._pressData.index, pos);
	    };
	    /**
	     * Handle the `'mouseup'` event for the split panel.
	     */
	    SplitPanel.prototype._evtMouseUp = function (event) {
	        // Do nothing if the left mouse button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Stop the event when releasing a handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Finalize the mouse release.
	        this._releaseMouse();
	    };
	    /**
	     * Release the mouse grab for the split panel.
	     */
	    SplitPanel.prototype._releaseMouse = function () {
	        // Bail early if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Clear the override cursor.
	        this._pressData.override.dispose();
	        this._pressData = null;
	        // Remove the extra document listeners.
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	    };
	    return SplitPanel;
	}(panel_1.Panel));
	exports.SplitPanel = SplitPanel;
	/**
	 * The namespace for the `SplitPanel` class statics.
	 */
	(function (SplitPanel) {
	    /**
	     * The default implementation of `IRenderer`.
	     */
	    var Renderer = (function () {
	        function Renderer() {
	        }
	        /**
	         * Create a new handle for use with a split panel.
	         *
	         * @returns A new handle element for a split panel.
	         */
	        Renderer.prototype.createHandle = function () {
	            var handle = document.createElement('div');
	            handle.className = 'p-SplitPanel-handle';
	            return handle;
	        };
	        return Renderer;
	    }());
	    SplitPanel.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    SplitPanel.defaultRenderer = new Renderer();
	    /**
	     * Get the split panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The split panel stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return splitlayout_1.SplitLayout.getStretch(widget);
	    }
	    SplitPanel.getStretch = getStretch;
	    /**
	     * Set the split panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        splitlayout_1.SplitLayout.setStretch(widget, value);
	    }
	    SplitPanel.setStretch = setStretch;
	})(SplitPanel = exports.SplitPanel || (exports.SplitPanel = {}));
	exports.SplitPanel = SplitPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a split layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new splitlayout_1.SplitLayout({
	            renderer: options.renderer || SplitPanel.defaultRenderer,
	            orientation: options.orientation,
	            alignment: options.alignment,
	            spacing: options.spacing
	        });
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __webpack_require__(175);
	var domutils_1 = __webpack_require__(192);
	var messaging_1 = __webpack_require__(196);
	var layout_1 = __webpack_require__(200);
	var panellayout_1 = __webpack_require__(204);
	var widget_1 = __webpack_require__(202);
	/**
	 * A layout where visible widgets are stacked atop one another.
	 *
	 * #### Notes
	 * The Z-order of the visible widgets follows their layout order.
	 */
	var StackedLayout = (function (_super) {
	    __extends(StackedLayout, _super);
	    function StackedLayout() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._dirty = false;
	        _this._items = [];
	        _this._box = null;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    StackedLayout.prototype.dispose = function () {
	        // Dispose of the layout items.
	        algorithm_1.each(this._items, function (item) { item.dispose(); });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.attachWidget = function (index, widget) {
	        // Create and add a new layout item for the widget.
	        algorithm_1.ArrayExt.insert(this._items, index, new layout_1.LayoutItem(widget));
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Move the layout item for the widget.
	        algorithm_1.ArrayExt.move(this._items, fromIndex, toIndex);
	        // Post an update request for the parent widget.
	        this.parent.update();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.detachWidget = function (index, widget) {
	        // Remove the layout item for the widget.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Reset the z-index for the widget.
	        item.widget.node.style.zIndex = '';
	        // Dispose of the layout item.
	        item.dispose();
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    StackedLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    StackedLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    StackedLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    StackedLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    StackedLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    StackedLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    StackedLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    StackedLayout.prototype._fit = function () {
	        // Set up the computed minimum size.
	        var minW = 0;
	        var minH = 0;
	        // Update the computed minimum size.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Update the size limits for the item.
	            item.fit();
	            // Update the computed minimum size.
	            minW = Math.max(minW, item.minWidth);
	            minH = Math.max(minH, item.minHeight);
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    StackedLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Bail early if there are no visible items to layout.
	        if (nVisible === 0) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the actual layout bounds adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Update the widget stacking order and layout geometry.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Set the z-index for the widget.
	            item.widget.node.style.zIndex = "" + i;
	            // Update the item geometry.
	            item.update(left, top, width, height);
	        }
	    };
	    return StackedLayout;
	}(panellayout_1.PanelLayout));
	exports.StackedLayout = StackedLayout;


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var signaling_1 = __webpack_require__(201);
	var panel_1 = __webpack_require__(206);
	var stackedlayout_1 = __webpack_require__(224);
	/**
	 * A panel where visible widgets are stacked atop one another.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[StackedLayout]].
	 */
	var StackedPanel = (function (_super) {
	    __extends(StackedPanel, _super);
	    /**
	     * Construct a new stacked panel.
	     *
	     * @param options - The options for initializing the panel.
	     */
	    function StackedPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { layout: Private.createLayout(options) }) || this;
	        _this._widgetRemoved = new signaling_1.Signal(_this);
	        _this.addClass('p-StackedPanel');
	        return _this;
	    }
	    Object.defineProperty(StackedPanel.prototype, "widgetRemoved", {
	        /**
	         * A signal emitted when a widget is removed from a stacked panel.
	         */
	        get: function () {
	            return this._widgetRemoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    StackedPanel.prototype.onChildAdded = function (msg) {
	        msg.child.addClass('p-StackedPanel-child');
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    StackedPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass('p-StackedPanel-child');
	        this._widgetRemoved.emit(msg.child);
	    };
	    return StackedPanel;
	}(panel_1.Panel));
	exports.StackedPanel = StackedPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a stacked layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new stackedlayout_1.StackedLayout();
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));


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

	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var domutils_1 = __webpack_require__(192);
	var messaging_1 = __webpack_require__(196);
	var signaling_1 = __webpack_require__(201);
	var boxlayout_1 = __webpack_require__(174);
	var stackedpanel_1 = __webpack_require__(225);
	var tabbar_1 = __webpack_require__(217);
	var widget_1 = __webpack_require__(202);
	/**
	 * A widget which combines a `TabBar` and a `StackedPanel`.
	 *
	 * #### Notes
	 * This is a simple panel which handles the common case of a tab bar
	 * placed next to a content area. The selected tab controls the widget
	 * which is shown in the content area.
	 *
	 * For use cases which require more control than is provided by this
	 * panel, the `TabBar` widget may be used independently.
	 */
	var TabPanel = (function (_super) {
	    __extends(TabPanel, _super);
	    /**
	     * Construct a new tab panel.
	     *
	     * @param options - The options for initializing the tab panel.
	     */
	    function TabPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._currentChanged = new signaling_1.Signal(_this);
	        _this.addClass('p-TabPanel');
	        // Create the tab bar and stacked panel.
	        _this.tabBar = new tabbar_1.TabBar(options);
	        _this.tabBar.addClass('p-TabPanel-tabBar');
	        _this.stackedPanel = new stackedpanel_1.StackedPanel();
	        _this.stackedPanel.addClass('p-TabPanel-stackedPanel');
	        // Connect the tab bar signal handlers.
	        _this.tabBar.tabMoved.connect(_this._onTabMoved, _this);
	        _this.tabBar.currentChanged.connect(_this._onCurrentChanged, _this);
	        _this.tabBar.tabCloseRequested.connect(_this._onTabCloseRequested, _this);
	        _this.tabBar.tabActivateRequested.connect(_this._onTabActivateRequested, _this);
	        // Connect the stacked panel signal handlers.
	        _this.stackedPanel.widgetRemoved.connect(_this._onWidgetRemoved, _this);
	        // Get the data related to the placement.
	        _this._tabPlacement = options.tabPlacement || 'top';
	        var direction = Private.directionFromPlacement(_this._tabPlacement);
	        var orientation = Private.orientationFromPlacement(_this._tabPlacement);
	        // Configure the tab bar for the placement.
	        _this.tabBar.orientation = orientation;
	        _this.tabBar.dataset['placement'] = _this._tabPlacement;
	        // Create the box layout.
	        var layout = new boxlayout_1.BoxLayout({ direction: direction, spacing: 0 });
	        // Set the stretch factors for the child widgets.
	        boxlayout_1.BoxLayout.setStretch(_this.tabBar, 0);
	        boxlayout_1.BoxLayout.setStretch(_this.stackedPanel, 1);
	        // Add the child widgets to the layout.
	        layout.addWidget(_this.tabBar);
	        layout.addWidget(_this.stackedPanel);
	        // Install the layout on the tab panel.
	        _this.layout = layout;
	        return _this;
	    }
	    Object.defineProperty(TabPanel.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current tab is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected tab is changed
	         * either through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current
	         * tab changes due to tabs being inserted, removed, or moved. It is
	         * only emitted when the actual current tab node is changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentIndex", {
	        /**
	         * Get the index of the currently selected tab.
	         *
	         * #### Notes
	         * This will be `-1` if no tab is selected.
	         */
	        get: function () {
	            return this.tabBar.currentIndex;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * #### Notes
	         * If the index is out of range, it will be set to `-1`.
	         */
	        set: function (value) {
	            this.tabBar.currentIndex = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentWidget", {
	        /**
	         * Get the currently selected widget.
	         *
	         * #### Notes
	         * This will be `null` if there is no selected tab.
	         */
	        get: function () {
	            var title = this.tabBar.currentTitle;
	            return title ? title.owner : null;
	        },
	        /**
	         * Set the currently selected widget.
	         *
	         * #### Notes
	         * If the widget is not in the panel, it will be set to `null`.
	         */
	        set: function (value) {
	            this.tabBar.currentTitle = value ? value.title : null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabsMovable", {
	        /**
	         * Get the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        get: function () {
	            return this.tabBar.tabsMovable;
	        },
	        /**
	         * Set the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        set: function (value) {
	            this.tabBar.tabsMovable = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabPlacement", {
	        /**
	         * Get the tab placement for the tab panel.
	         *
	         * #### Notes
	         * This controls the position of the tab bar relative to the content.
	         */
	        get: function () {
	            return this._tabPlacement;
	        },
	        /**
	         * Set the tab placement for the tab panel.
	         *
	         * #### Notes
	         * This controls the position of the tab bar relative to the content.
	         */
	        set: function (value) {
	            // Bail if the placement does not change.
	            if (this._tabPlacement === value) {
	                return;
	            }
	            // Update the internal value.
	            this._tabPlacement = value;
	            // Get the values related to the placement.
	            var direction = Private.directionFromPlacement(value);
	            var orientation = Private.orientationFromPlacement(value);
	            // Configure the tab bar for the placement.
	            this.tabBar.orientation = orientation;
	            this.tabBar.dataset['placement'] = value;
	            // Update the layout direction.
	            this.layout.direction = direction;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the panel.
	         */
	        get: function () {
	            return this.stackedPanel.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a widget to the end of the tab panel.
	     *
	     * @param widget - The widget to add to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.addWidget = function (widget) {
	        this.insertWidget(this.widgets.length, widget);
	    };
	    /**
	     * Insert a widget into the tab panel at a specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.insertWidget = function (index, widget) {
	        if (widget !== this.currentWidget) {
	            widget.hide();
	        }
	        this.stackedPanel.insertWidget(index, widget);
	        this.tabBar.insertTab(index, widget.title);
	    };
	    /**
	     * Handle the `currentChanged` signal from the tab bar.
	     */
	    TabPanel.prototype._onCurrentChanged = function (sender, args) {
	        // Extract the previous and current title from the args.
	        var previousIndex = args.previousIndex, previousTitle = args.previousTitle, currentIndex = args.currentIndex, currentTitle = args.currentTitle;
	        // Extract the widgets from the titles.
	        var previousWidget = previousTitle ? previousTitle.owner : null;
	        var currentWidget = currentTitle ? currentTitle.owner : null;
	        // Hide the previous widget.
	        if (previousWidget) {
	            previousWidget.hide();
	        }
	        // Show the current widget.
	        if (currentWidget) {
	            currentWidget.show();
	        }
	        // Emit the `currentChanged` signal for the tab panel.
	        this._currentChanged.emit({
	            previousIndex: previousIndex, previousWidget: previousWidget, currentIndex: currentIndex, currentWidget: currentWidget
	        });
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	    };
	    /**
	     * Handle the `tabActivateRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabActivateRequested = function (sender, args) {
	        args.title.owner.activate();
	    };
	    /**
	     * Handle the `tabCloseRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabCloseRequested = function (sender, args) {
	        args.title.owner.close();
	    };
	    /**
	     * Handle the `tabMoved` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabMoved = function (sender, args) {
	        this.stackedPanel.insertWidget(args.toIndex, args.title.owner);
	    };
	    /**
	     * Handle the `widgetRemoved` signal from the stacked panel.
	     */
	    TabPanel.prototype._onWidgetRemoved = function (sender, widget) {
	        this.tabBar.removeTab(widget.title);
	    };
	    return TabPanel;
	}(widget_1.Widget));
	exports.TabPanel = TabPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Convert a tab placement to tab bar orientation.
	     */
	    function orientationFromPlacement(plc) {
	        return placementToOrientationMap[plc];
	    }
	    Private.orientationFromPlacement = orientationFromPlacement;
	    /**
	     * Convert a tab placement to a box layout direction.
	     */
	    function directionFromPlacement(plc) {
	        return placementToDirectionMap[plc];
	    }
	    Private.directionFromPlacement = directionFromPlacement;
	    /**
	     * A mapping of tab placement to tab bar orientation.
	     */
	    var placementToOrientationMap = {
	        'top': 'horizontal',
	        'left': 'vertical',
	        'right': 'vertical',
	        'bottom': 'horizontal'
	    };
	    /**
	     * A mapping of tab placement to box layout direction.
	     */
	    var placementToDirectionMap = {
	        'top': 'top-to-bottom',
	        'left': 'left-to-right',
	        'right': 'right-to-left',
	        'bottom': 'bottom-to-top'
	    };
	})(Private || (Private = {}));


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils_1 = __webpack_require__(4);
	var widget_1 = __webpack_require__(166);
	/**
	 * css properties exposed by the layout widget with their default values.
	 */
	var css_properties = {
	    align_content: null,
	    align_items: null,
	    align_self: null,
	    border: null,
	    bottom: null,
	    display: null,
	    flex: null,
	    flex_flow: null,
	    height: null,
	    justify_content: null,
	    left: null,
	    margin: null,
	    max_height: null,
	    max_width: null,
	    min_height: null,
	    min_width: null,
	    overflow: null,
	    overflow_x: null,
	    overflow_y: null,
	    order: null,
	    padding: null,
	    right: null,
	    top: null,
	    visibility: null,
	    width: null
	};
	var LayoutModel = /** @class */ (function (_super) {
	    __extends(LayoutModel, _super);
	    function LayoutModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LayoutModel.prototype.defaults = function () {
	        return utils_1.assign(_super.prototype.defaults.call(this), {
	            _model_name: 'LayoutModel',
	            _view_name: 'LayoutView'
	        }, css_properties);
	    };
	    return LayoutModel;
	}(widget_1.WidgetModel));
	exports.LayoutModel = LayoutModel;
	var LayoutView = /** @class */ (function (_super) {
	    __extends(LayoutView, _super);
	    function LayoutView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    LayoutView.prototype.initialize = function (parameters) {
	        this._traitNames = [];
	        _super.prototype.initialize.call(this, parameters);
	        // Register the traits that live on the Python side
	        for (var _i = 0, _a = Object.keys(css_properties); _i < _a.length; _i++) {
	            var key = _a[_i];
	            this.registerTrait(key);
	        }
	    };
	    /**
	     * Register a CSS trait that is known by the model
	     * @param trait
	     */
	    LayoutView.prototype.registerTrait = function (trait) {
	        var _this = this;
	        this._traitNames.push(trait);
	        // Listen to changes, and set the value on change.
	        this.listenTo(this.model, 'change:' + trait, function (model, value) {
	            _this.handleChange(trait, value);
	        });
	        // Set the initial value on display.
	        this.handleChange(trait, this.model.get(trait));
	    };
	    /**
	     * Get the the name of the css property from the trait name
	     * @param  model attribute name
	     * @return css property name
	     */
	    LayoutView.prototype.css_name = function (trait) {
	        return trait.replace('_', '-');
	    };
	    /**
	     * Handles when a trait value changes
	     */
	    LayoutView.prototype.handleChange = function (trait, value) {
	        // should be synchronous so that we can measure later.
	        var parent = this.options.parent;
	        if (parent) {
	            if (value === null) {
	                parent.el.style.removeProperty(this.css_name(trait));
	            }
	            else {
	                parent.el.style[this.css_name(trait)] = value;
	            }
	        }
	        else {
	            console.warn('Style not applied because a parent view does not exist');
	        }
	    };
	    /**
	     * Remove the styling from the parent view.
	     */
	    LayoutView.prototype.unlayout = function () {
	        var _this = this;
	        var parent = this.options.parent;
	        this._traitNames.forEach(function (trait) {
	            if (parent) {
	                parent.el.style.removeProperty(_this.css_name(trait));
	            }
	            else {
	                console.warn('Style not removed because a parent view does not exist');
	            }
	        }, this);
	    };
	    return LayoutView;
	}(widget_1.WidgetView));
	exports.LayoutView = LayoutView;


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils_1 = __webpack_require__(4);
	var widget_1 = __webpack_require__(166);
	var StyleModel = /** @class */ (function (_super) {
	    __extends(StyleModel, _super);
	    function StyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    StyleModel.prototype.defaults = function () {
	        var Derived = this.constructor;
	        return utils_1.assign(_super.prototype.defaults.call(this), {
	            _model_name: 'StyleModel',
	            _view_name: 'StyleView',
	        }, Object.keys(Derived.styleProperties).reduce(function (obj, key) {
	            obj[key] = Derived.styleProperties[key].default;
	            return obj;
	        }, {}));
	    };
	    StyleModel.styleProperties = {};
	    return StyleModel;
	}(widget_1.WidgetModel));
	exports.StyleModel = StyleModel;
	var StyleView = /** @class */ (function (_super) {
	    __extends(StyleView, _super);
	    function StyleView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    StyleView.prototype.initialize = function (parameters) {
	        this._traitNames = [];
	        _super.prototype.initialize.call(this, parameters);
	        // Register the traits that live on the Python side
	        var ModelType = this.model.constructor;
	        for (var _i = 0, _a = Object.keys(ModelType.styleProperties); _i < _a.length; _i++) {
	            var key = _a[_i];
	            this.registerTrait(key);
	        }
	        // Set the initial styles
	        this.style();
	    };
	    /**
	     * Register a CSS trait that is known by the model
	     * @param trait
	     */
	    StyleView.prototype.registerTrait = function (trait) {
	        var _this = this;
	        this._traitNames.push(trait);
	        // Listen to changes, and set the value on change.
	        this.listenTo(this.model, 'change:' + trait, function (model, value) {
	            _this.handleChange(trait, value);
	        });
	    };
	    /**
	     * Handles when a trait value changes
	     */
	    StyleView.prototype.handleChange = function (trait, value) {
	        // should be synchronous so that we can measure later.
	        var parent = this.options.parent;
	        if (parent) {
	            var ModelType = this.model.constructor;
	            var styleProperties = ModelType.styleProperties;
	            var attribute = styleProperties[trait].attribute;
	            var selector = styleProperties[trait].selector;
	            var elements = selector ? parent.el.querySelectorAll(selector) : [parent.el];
	            if (value === null) {
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style.removeProperty(attribute);
	                }
	            }
	            else {
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style[attribute] = value;
	                }
	            }
	        }
	        else {
	            console.warn('Style not applied because a parent view does not exist');
	        }
	    };
	    /**
	     * Apply styles for all registered traits
	     */
	    StyleView.prototype.style = function () {
	        for (var _i = 0, _a = this._traitNames; _i < _a.length; _i++) {
	            var trait = _a[_i];
	            this.handleChange(trait, this.model.get(trait));
	        }
	    };
	    /**
	     * Remove the styling from the parent view.
	     */
	    StyleView.prototype.unstyle = function () {
	        var parent = this.options.parent;
	        var ModelType = this.model.constructor;
	        var styleProperties = ModelType.styleProperties;
	        this._traitNames.forEach(function (trait) {
	            if (parent) {
	                var attribute = styleProperties[trait].attribute;
	                var selector = styleProperties[trait].selector;
	                var elements = selector ? parent.el.querySelectorAll(selector) : [parent.el];
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style.removeProperty(attribute);
	                }
	            }
	            else {
	                console.warn('Style not removed because a parent view does not exist');
	            }
	        }, this);
	    };
	    return StyleView;
	}(widget_1.WidgetView));
	exports.StyleView = StyleView;


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var shims;
	(function (shims) {
	    var services;
	    (function (services) {
	        /**
	         * Public constructor
	         * @param jsServicesKernel - @jupyterlab/services Kernel.IKernel instance
	         */
	        var CommManager = /** @class */ (function () {
	            function CommManager(jsServicesKernel) {
	                this.targets = Object.create(null);
	                this.comms = Object.create(null);
	                this.kernel = null;
	                this.jsServicesKernel = null;
	                this.init_kernel(jsServicesKernel);
	            }
	            /**
	             * Hookup kernel events.
	             * @param  {Kernel.IKernel} jsServicesKernel - @jupyterlab/services Kernel.IKernel instance
	             */
	            CommManager.prototype.init_kernel = function (jsServicesKernel) {
	                this.kernel = jsServicesKernel; // These aren't really the same.
	                this.jsServicesKernel = jsServicesKernel;
	            };
	            /**
	             * Creates a new connected comm
	             * @param  {string} target_name
	             * @param  {object} data
	             * @param  {object} callbacks
	             * @param  {object} metadata
	             * @param  {string} comm_id
	             * @return {Comm}
	             */
	            CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata, comm_id, buffers) {
	                var comm = new Comm(this.jsServicesKernel.connectToComm(target_name, comm_id));
	                this.register_comm(comm);
	                comm.open(data, callbacks, metadata, buffers);
	                return comm;
	            };
	            /**
	             * Register a comm target
	             * @param  {string} target_name
	             * @param  {(Comm, object) => void} f - callback that is called when the
	             *                         comm is made.  Signature of f(comm, msg).
	             */
	            CommManager.prototype.register_target = function (target_name, f) {
	                var _this = this;
	                var handle = this.jsServicesKernel.registerCommTarget(target_name, function (jsServicesComm, msg) {
	                    // Create the comm.
	                    var comm = new Comm(jsServicesComm);
	                    _this.register_comm(comm);
	                    // Call the callback for the comm.
	                    try {
	                        return f(comm, msg);
	                    }
	                    catch (e) {
	                        comm.close();
	                        console.error(e);
	                        console.error(new Error('Exception opening new comm'));
	                    }
	                });
	                this.targets[target_name] = handle;
	            };
	            /**
	             * Unregisters a comm target
	             * @param  {string} target_name
	             */
	            CommManager.prototype.unregister_target = function (target_name, f) {
	                var handle = this.targets[target_name];
	                handle.dispose();
	                delete this.targets[target_name];
	            };
	            /**
	             * Register a comm in the mapping
	             */
	            CommManager.prototype.register_comm = function (comm) {
	                this.comms[comm.comm_id] = Promise.resolve(comm);
	                comm.kernel = this.kernel;
	                return comm.comm_id;
	            };
	            ;
	            return CommManager;
	        }());
	        services.CommManager = CommManager;
	        /**
	         * Public constructor
	         * @param  {IComm} jsServicesComm - @jupyterlab/services IComm instance
	         */
	        var Comm = /** @class */ (function () {
	            function Comm(jsServicesComm) {
	                this.jsServicesComm = null;
	                this.jsServicesComm = jsServicesComm;
	            }
	            Object.defineProperty(Comm.prototype, "comm_id", {
	                /**
	                 * Comm id
	                 * @return {string}
	                 */
	                get: function () {
	                    return this.jsServicesComm.commId;
	                },
	                enumerable: true,
	                configurable: true
	            });
	            Object.defineProperty(Comm.prototype, "target_name", {
	                /**
	                 * Target name
	                 * @return {string}
	                 */
	                get: function () {
	                    return this.jsServicesComm.targetName;
	                },
	                enumerable: true,
	                configurable: true
	            });
	            /**
	             * Opens a sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @return msg id
	             */
	            Comm.prototype.open = function (data, callbacks, metadata, buffers) {
	                var future = this.jsServicesComm.open(data, metadata, buffers);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            /**
	             * Sends a message to the sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @param  buffers
	             * @return message id
	             */
	            Comm.prototype.send = function (data, callbacks, metadata, buffers) {
	                var future = this.jsServicesComm.send(data, metadata, buffers);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            /**
	             * Closes the sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @return msg id
	             */
	            Comm.prototype.close = function (data, callbacks, metadata, buffers) {
	                var future = this.jsServicesComm.close(data, metadata, buffers);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            /**
	             * Register a message handler
	             * @param  callback, which is given a message
	             */
	            Comm.prototype.on_msg = function (callback) {
	                this.jsServicesComm.onMsg = callback.bind(this);
	            };
	            /**
	             * Register a handler for when the comm is closed by the backend
	             * @param  callback, which is given a message
	             */
	            Comm.prototype.on_close = function (callback) {
	                this.jsServicesComm.onClose = callback.bind(this);
	            };
	            /**
	             * Hooks callback object up with @jupyterlab/services IKernelFuture
	             * @param  @jupyterlab/services IKernelFuture instance
	             * @param  callbacks
	             */
	            Comm.prototype._hookupCallbacks = function (future, callbacks) {
	                if (callbacks) {
	                    future.onReply = function (msg) {
	                        if (callbacks.shell && callbacks.shell.reply) {
	                            callbacks.shell.reply(msg);
	                        }
	                        // TODO: Handle payloads.  See https://github.com/jupyter/notebook/blob/master/notebook/static/services/kernels/kernel.js#L923-L947
	                    };
	                    future.onStdin = function (msg) {
	                        if (callbacks.input) {
	                            callbacks.input(msg);
	                        }
	                    };
	                    future.onIOPub = function (msg) {
	                        if (callbacks.iopub) {
	                            if (callbacks.iopub.status && msg.header.msg_type === 'status') {
	                                callbacks.iopub.status(msg);
	                            }
	                            else if (callbacks.iopub.clear_output && msg.header.msg_type === 'clear_output') {
	                                callbacks.iopub.clear_output(msg);
	                            }
	                            else if (callbacks.iopub.output) {
	                                switch (msg.header.msg_type) {
	                                    case 'display_data':
	                                    case 'execute_result':
	                                        callbacks.iopub.output(msg);
	                                        break;
	                                }
	                            }
	                        }
	                    };
	                }
	            };
	            return Comm;
	        }());
	        services.Comm = Comm;
	    })(services = shims.services || (shims.services = {}));
	})(shims = exports.shims || (exports.shims = {}));


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * - create_view and remove_view are default functions called when adding or removing views
	 * - create_view takes a model and an index and returns a view or a promise for a view for that model
	 * - remove_view takes a view and destroys it (including calling `view.remove()`)
	 * - each time the update() function is called with a new list, the create and remove
	 *   callbacks will be called in an order so that if you append the views created in the
	 *   create callback and remove the views in the remove callback, you will duplicate
	 *   the order of the list.
	 * - the remove callback defaults to just removing the view (e.g., pass in null for the second parameter)
	 * - the context defaults to the created ViewList.  If you pass another context, the create and remove
	 *   will be called in that context.
	 */
	var ViewList = /** @class */ (function () {
	    function ViewList(create_view, remove_view, context) {
	        this.initialize(create_view, remove_view, context);
	    }
	    ViewList.prototype.initialize = function (create_view, remove_view, context) {
	        this._handler_context = context || this;
	        this._models = [];
	        this.views = []; // list of promises for views
	        this._create_view = create_view;
	        this._remove_view = remove_view || function (view) { view.remove(); };
	    };
	    /**
	     * the create_view, remove_view, and context arguments override the defaults
	     * specified when the list is created.
	     * after this function, the .views attribute is a list of promises for views
	     * if you want to perform some action on the list of views, do something like
	     * `Promise.all(myviewlist.views).then(function(views) {...});`
	     */
	    ViewList.prototype.update = function (new_models, create_view, remove_view, context) {
	        var remove = remove_view || this._remove_view;
	        var create = create_view || this._create_view;
	        context = context || this._handler_context;
	        var i = 0;
	        // first, skip past the beginning of the lists if they are identical
	        for (; i < new_models.length; i++) {
	            if (i >= this._models.length || new_models[i] !== this._models[i]) {
	                break;
	            }
	        }
	        var first_removed = i;
	        // Remove the non-matching items from the old list.
	        var removed = this.views.splice(first_removed, this.views.length - first_removed);
	        for (var j = 0; j < removed.length; j++) {
	            removed[j].then(function (view) {
	                remove.call(context, view);
	            });
	        }
	        // Add the rest of the new list items.
	        for (; i < new_models.length; i++) {
	            this.views.push(Promise.resolve(create.call(context, new_models[i], i)));
	        }
	        // make a copy of the input array
	        this._models = new_models.slice();
	        // return a promise that resolves to all of the resolved views
	        return Promise.all(this.views);
	    };
	    /**
	     * removes every view in the list; convenience function for `.update([])`
	     * that should be faster
	     * returns a promise that resolves after this removal is done
	     */
	    ViewList.prototype.remove = function () {
	        var _this = this;
	        return Promise.all(this.views).then(function (views) {
	            views.forEach(function (value) { return _this._remove_view.call(_this._handler_context, value); });
	            _this.views = [];
	            _this._models = [];
	        });
	    };
	    /**
	     * Dispose this viewlist.
	     *
	     * A synchronous function which just deletes references to child views. This
	     * function does not call .remove() on child views because that is
	     * asynchronous. Use this in cases where child views will be removed in
	     * another way.
	     */
	    ViewList.prototype.dispose = function () {
	        this.views = null;
	        this._models = null;
	    };
	    return ViewList;
	}());
	exports.ViewList = ViewList;


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

	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __webpack_require__(6);
	/**
	 * A runtime interface token for a widget registry.
	 */
	exports.IJupyterWidgetRegistry = new coreutils_1.Token('jupyter.extensions.jupyterWidgetRegistry');


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

	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global, module) {/**
	 * @license
	 * Lodash <https://lodash.com/>
	 * Copyright JS Foundation and other contributors <https://js.foundation/>
	 * Released under MIT license <https://lodash.com/license>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 */
	;(function() {
	
	  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
	  var undefined;
	
	  /** Used as the semantic version number. */
	  var VERSION = '4.17.4';
	
	  /** Used as the size to enable large array optimizations. */
	  var LARGE_ARRAY_SIZE = 200;
	
	  /** Error message constants. */
	  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
	      FUNC_ERROR_TEXT = 'Expected a function';
	
	  /** Used to stand-in for `undefined` hash values. */
	  var HASH_UNDEFINED = '__lodash_hash_undefined__';
	
	  /** Used as the maximum memoize cache size. */
	  var MAX_MEMOIZE_SIZE = 500;
	
	  /** Used as the internal argument placeholder. */
	  var PLACEHOLDER = '__lodash_placeholder__';
	
	  /** Used to compose bitmasks for cloning. */
	  var CLONE_DEEP_FLAG = 1,
	      CLONE_FLAT_FLAG = 2,
	      CLONE_SYMBOLS_FLAG = 4;
	
	  /** Used to compose bitmasks for value comparisons. */
	  var COMPARE_PARTIAL_FLAG = 1,
	      COMPARE_UNORDERED_FLAG = 2;
	
	  /** Used to compose bitmasks for function metadata. */
	  var WRAP_BIND_FLAG = 1,
	      WRAP_BIND_KEY_FLAG = 2,
	      WRAP_CURRY_BOUND_FLAG = 4,
	      WRAP_CURRY_FLAG = 8,
	      WRAP_CURRY_RIGHT_FLAG = 16,
	      WRAP_PARTIAL_FLAG = 32,
	      WRAP_PARTIAL_RIGHT_FLAG = 64,
	      WRAP_ARY_FLAG = 128,
	      WRAP_REARG_FLAG = 256,
	      WRAP_FLIP_FLAG = 512;
	
	  /** Used as default options for `_.truncate`. */
	  var DEFAULT_TRUNC_LENGTH = 30,
	      DEFAULT_TRUNC_OMISSION = '...';
	
	  /** Used to detect hot functions by number of calls within a span of milliseconds. */
	  var HOT_COUNT = 800,
	      HOT_SPAN = 16;
	
	  /** Used to indicate the type of lazy iteratees. */
	  var LAZY_FILTER_FLAG = 1,
	      LAZY_MAP_FLAG = 2,
	      LAZY_WHILE_FLAG = 3;
	
	  /** Used as references for various `Number` constants. */
	  var INFINITY = 1 / 0,
	      MAX_SAFE_INTEGER = 9007199254740991,
	      MAX_INTEGER = 1.7976931348623157e+308,
	      NAN = 0 / 0;
	
	  /** Used as references for the maximum length and index of an array. */
	  var MAX_ARRAY_LENGTH = 4294967295,
	      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
	      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
	
	  /** Used to associate wrap methods with their bit flags. */
	  var wrapFlags = [
	    ['ary', WRAP_ARY_FLAG],
	    ['bind', WRAP_BIND_FLAG],
	    ['bindKey', WRAP_BIND_KEY_FLAG],
	    ['curry', WRAP_CURRY_FLAG],
	    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
	    ['flip', WRAP_FLIP_FLAG],
	    ['partial', WRAP_PARTIAL_FLAG],
	    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
	    ['rearg', WRAP_REARG_FLAG]
	  ];
	
	  /** `Object#toString` result references. */
	  var argsTag = '[object Arguments]',
	      arrayTag = '[object Array]',
	      asyncTag = '[object AsyncFunction]',
	      boolTag = '[object Boolean]',
	      dateTag = '[object Date]',
	      domExcTag = '[object DOMException]',
	      errorTag = '[object Error]',
	      funcTag = '[object Function]',
	      genTag = '[object GeneratorFunction]',
	      mapTag = '[object Map]',
	      numberTag = '[object Number]',
	      nullTag = '[object Null]',
	      objectTag = '[object Object]',
	      promiseTag = '[object Promise]',
	      proxyTag = '[object Proxy]',
	      regexpTag = '[object RegExp]',
	      setTag = '[object Set]',
	      stringTag = '[object String]',
	      symbolTag = '[object Symbol]',
	      undefinedTag = '[object Undefined]',
	      weakMapTag = '[object WeakMap]',
	      weakSetTag = '[object WeakSet]';
	
	  var arrayBufferTag = '[object ArrayBuffer]',
	      dataViewTag = '[object DataView]',
	      float32Tag = '[object Float32Array]',
	      float64Tag = '[object Float64Array]',
	      int8Tag = '[object Int8Array]',
	      int16Tag = '[object Int16Array]',
	      int32Tag = '[object Int32Array]',
	      uint8Tag = '[object Uint8Array]',
	      uint8ClampedTag = '[object Uint8ClampedArray]',
	      uint16Tag = '[object Uint16Array]',
	      uint32Tag = '[object Uint32Array]';
	
	  /** Used to match empty string literals in compiled template source. */
	  var reEmptyStringLeading = /\b__p \+= '';/g,
	      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
	      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
	
	  /** Used to match HTML entities and HTML characters. */
	  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
	      reUnescapedHtml = /[&<>"']/g,
	      reHasEscapedHtml = RegExp(reEscapedHtml.source),
	      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
	
	  /** Used to match template delimiters. */
	  var reEscape = /<%-([\s\S]+?)%>/g,
	      reEvaluate = /<%([\s\S]+?)%>/g,
	      reInterpolate = /<%=([\s\S]+?)%>/g;
	
	  /** Used to match property names within property paths. */
	  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
	      reIsPlainProp = /^\w*$/,
	      reLeadingDot = /^\./,
	      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
	
	  /**
	   * Used to match `RegExp`
	   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
	   */
	  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
	      reHasRegExpChar = RegExp(reRegExpChar.source);
	
	  /** Used to match leading and trailing whitespace. */
	  var reTrim = /^\s+|\s+$/g,
	      reTrimStart = /^\s+/,
	      reTrimEnd = /\s+$/;
	
	  /** Used to match wrap detail comments. */
	  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
	      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
	      reSplitDetails = /,? & /;
	
	  /** Used to match words composed of alphanumeric characters. */
	  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
	
	  /** Used to match backslashes in property paths. */
	  var reEscapeChar = /\\(\\)?/g;
	
	  /**
	   * Used to match
	   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
	   */
	  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
	
	  /** Used to match `RegExp` flags from their coerced string values. */
	  var reFlags = /\w*$/;
	
	  /** Used to detect bad signed hexadecimal string values. */
	  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
	
	  /** Used to detect binary string values. */
	  var reIsBinary = /^0b[01]+$/i;
	
	  /** Used to detect host constructors (Safari). */
	  var reIsHostCtor = /^\[object .+?Constructor\]$/;
	
	  /** Used to detect octal string values. */
	  var reIsOctal = /^0o[0-7]+$/i;
	
	  /** Used to detect unsigned integer values. */
	  var reIsUint = /^(?:0|[1-9]\d*)$/;
	
	  /** Used to match Latin Unicode letters (excluding mathematical operators). */
	  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
	
	  /** Used to ensure capturing order of template delimiters. */
	  var reNoMatch = /($^)/;
	
	  /** Used to match unescaped characters in compiled string literals. */
	  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
	
	  /** Used to compose unicode character classes. */
	  var rsAstralRange = '\\ud800-\\udfff',
	      rsComboMarksRange = '\\u0300-\\u036f',
	      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
	      rsComboSymbolsRange = '\\u20d0-\\u20ff',
	      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
	      rsDingbatRange = '\\u2700-\\u27bf',
	      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
	      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
	      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
	      rsPunctuationRange = '\\u2000-\\u206f',
	      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
	      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
	      rsVarRange = '\\ufe0e\\ufe0f',
	      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
	
	  /** Used to compose unicode capture groups. */
	  var rsApos = "['\u2019]",
	      rsAstral = '[' + rsAstralRange + ']',
	      rsBreak = '[' + rsBreakRange + ']',
	      rsCombo = '[' + rsComboRange + ']',
	      rsDigits = '\\d+',
	      rsDingbat = '[' + rsDingbatRange + ']',
	      rsLower = '[' + rsLowerRange + ']',
	      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
	      rsFitz = '\\ud83c[\\udffb-\\udfff]',
	      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
	      rsNonAstral = '[^' + rsAstralRange + ']',
	      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
	      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
	      rsUpper = '[' + rsUpperRange + ']',
	      rsZWJ = '\\u200d';
	
	  /** Used to compose unicode regexes. */
	  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
	      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
	      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
	      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
	      reOptMod = rsModifier + '?',
	      rsOptVar = '[' + rsVarRange + ']?',
	      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
	      rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
	      rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
	      rsSeq = rsOptVar + reOptMod + rsOptJoin,
	      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
	      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
	
	  /** Used to match apostrophes. */
	  var reApos = RegExp(rsApos, 'g');
	
	  /**
	   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
	   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
	   */
	  var reComboMark = RegExp(rsCombo, 'g');
	
	  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
	  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
	
	  /** Used to match complex or compound words. */
	  var reUnicodeWord = RegExp([
	    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
	    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
	    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
	    rsUpper + '+' + rsOptContrUpper,
	    rsOrdUpper,
	    rsOrdLower,
	    rsDigits,
	    rsEmoji
	  ].join('|'), 'g');
	
	  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
	  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
	
	  /** Used to detect strings that need a more robust regexp to match words. */
	  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
	
	  /** Used to assign default `context` object properties. */
	  var contextProps = [
	    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
	    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
	    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
	    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
	    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
	  ];
	
	  /** Used to make template sourceURLs easier to identify. */
	  var templateCounter = -1;
	
	  /** Used to identify `toStringTag` values of typed arrays. */
	  var typedArrayTags = {};
	  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
	  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
	  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
	  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
	  typedArrayTags[uint32Tag] = true;
	  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
	  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
	  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
	  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
	  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
	  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
	  typedArrayTags[setTag] = typedArrayTags[stringTag] =
	  typedArrayTags[weakMapTag] = false;
	
	  /** Used to identify `toStringTag` values supported by `_.clone`. */
	  var cloneableTags = {};
	  cloneableTags[argsTag] = cloneableTags[arrayTag] =
	  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
	  cloneableTags[boolTag] = cloneableTags[dateTag] =
	  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
	  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
	  cloneableTags[int32Tag] = cloneableTags[mapTag] =
	  cloneableTags[numberTag] = cloneableTags[objectTag] =
	  cloneableTags[regexpTag] = cloneableTags[setTag] =
	  cloneableTags[stringTag] = cloneableTags[symbolTag] =
	  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
	  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
	  cloneableTags[errorTag] = cloneableTags[funcTag] =
	  cloneableTags[weakMapTag] = false;
	
	  /** Used to map Latin Unicode letters to basic Latin letters. */
	  var deburredLetters = {
	    // Latin-1 Supplement block.
	    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
	    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
	    '\xc7': 'C',  '\xe7': 'c',
	    '\xd0': 'D',  '\xf0': 'd',
	    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
	    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
	    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
	    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
	    '\xd1': 'N',  '\xf1': 'n',
	    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
	    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
	    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
	    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
	    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
	    '\xc6': 'Ae', '\xe6': 'ae',
	    '\xde': 'Th', '\xfe': 'th',
	    '\xdf': 'ss',
	    // Latin Extended-A block.
	    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
	    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
	    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
	    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
	    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
	    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
	    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
	    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
	    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
	    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
	    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
	    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
	    '\u0134': 'J',  '\u0135': 'j',
	    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
	    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
	    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
	    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
	    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
	    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
	    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
	    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
	    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
	    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
	    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
	    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
	    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
	    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
	    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
	    '\u0174': 'W',  '\u0175': 'w',
	    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
	    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
	    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
	    '\u0132': 'IJ', '\u0133': 'ij',
	    '\u0152': 'Oe', '\u0153': 'oe',
	    '\u0149': "'n", '\u017f': 's'
	  };
	
	  /** Used to map characters to HTML entities. */
	  var htmlEscapes = {
	    '&': '&amp;',
	    '<': '&lt;',
	    '>': '&gt;',
	    '"': '&quot;',
	    "'": '&#39;'
	  };
	
	  /** Used to map HTML entities to characters. */
	  var htmlUnescapes = {
	    '&amp;': '&',
	    '&lt;': '<',
	    '&gt;': '>',
	    '&quot;': '"',
	    '&#39;': "'"
	  };
	
	  /** Used to escape characters for inclusion in compiled string literals. */
	  var stringEscapes = {
	    '\\': '\\',
	    "'": "'",
	    '\n': 'n',
	    '\r': 'r',
	    '\u2028': 'u2028',
	    '\u2029': 'u2029'
	  };
	
	  /** Built-in method references without a dependency on `root`. */
	  var freeParseFloat = parseFloat,
	      freeParseInt = parseInt;
	
	  /** Detect free variable `global` from Node.js. */
	  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
	
	  /** Detect free variable `self`. */
	  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
	
	  /** Used as a reference to the global object. */
	  var root = freeGlobal || freeSelf || Function('return this')();
	
	  /** Detect free variable `exports`. */
	  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
	
	  /** Detect free variable `module`. */
	  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
	
	  /** Detect the popular CommonJS extension `module.exports`. */
	  var moduleExports = freeModule && freeModule.exports === freeExports;
	
	  /** Detect free variable `process` from Node.js. */
	  var freeProcess = moduleExports && freeGlobal.process;
	
	  /** Used to access faster Node.js helpers. */
	  var nodeUtil = (function() {
	    try {
	      return freeProcess && freeProcess.binding && freeProcess.binding('util');
	    } catch (e) {}
	  }());
	
	  /* Node.js helper references. */
	  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
	      nodeIsDate = nodeUtil && nodeUtil.isDate,
	      nodeIsMap = nodeUtil && nodeUtil.isMap,
	      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
	      nodeIsSet = nodeUtil && nodeUtil.isSet,
	      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
	
	  /*--------------------------------------------------------------------------*/
	
	  /**
	   * Adds the key-value `pair` to `map`.
	   *
	   * @private
	   * @param {Object} map The map to modify.
	   * @param {Array} pair The key-value pair to add.
	   * @returns {Object} Returns `map`.
	   */
	  function addMapEntry(map, pair) {
	    // Don't return `map.set` because it's not chainable in IE 11.
	    map.set(pair[0], pair[1]);
	    return map;
	  }
	
	  /**
	   * Adds `value` to `set`.
	   *
	   * @private
	   * @param {Object} set The set to modify.
	   * @param {*} value The value to add.
	   * @returns {Object} Returns `set`.
	   */
	  function addSetEntry(set, value) {
	    // Don't return `set.add` because it's not chainable in IE 11.
	    set.add(value);
	    return set;
	  }
	
	  /**
	   * A faster alternative to `Function#apply`, this function invokes `func`
	   * with the `this` binding of `thisArg` and the arguments of `args`.
	   *
	   * @private
	   * @param {Function} func The function to invoke.
	   * @param {*} thisArg The `this` binding of `func`.
	   * @param {Array} args The arguments to invoke `func` with.
	   * @returns {*} Returns the result of `func`.
	   */
	  function apply(func, thisArg, args) {
	    switch (args.length) {
	      case 0: return func.call(thisArg);
	      case 1: return func.call(thisArg, args[0]);
	      case 2: return func.call(thisArg, args[0], args[1]);
	      case 3: return func.call(thisArg, args[0], args[1], args[2]);
	    }
	    return func.apply(thisArg, args);
	  }
	
	  /**
	   * A specialized version of `baseAggregator` for arrays.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} setter The function to set `accumulator` values.
	   * @param {Function} iteratee The iteratee to transform keys.
	   * @param {Object} accumulator The initial aggregated object.
	   * @returns {Function} Returns `accumulator`.
	   */
	  function arrayAggregator(array, setter, iteratee, accumulator) {
	    var index = -1,
	        length = array == null ? 0 : array.length;
	
	    while (++index < length) {
	      var value = array[index];
	      setter(accumulator, value, iteratee(value), array);
	    }
	    return accumulator;
	  }
	
	  /**
	   * A specialized version of `_.forEach` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {Array} Returns `array`.
	   */
	  function arrayEach(array, iteratee) {
	    var index = -1,
	        length = array == null ? 0 : array.length;
	
	    while (++index < length) {
	      if (iteratee(array[index], index, array) === false) {
	        break;
	      }
	    }
	    return array;
	  }
	
	  /**
	   * A specialized version of `_.forEachRight` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {Array} Returns `array`.
	   */
	  function arrayEachRight(array, iteratee) {
	    var length = array == null ? 0 : array.length;
	
	    while (length--) {
	      if (iteratee(array[length], length, array) === false) {
	        break;
	      }
	    }
	    return array;
	  }
	
	  /**
	   * A specialized version of `_.every` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} predicate The function invoked per iteration.
	   * @returns {boolean} Returns `true` if all elements pass the predicate check,
	   *  else `false`.
	   */
	  function arrayEvery(array, predicate) {
	    var index = -1,
	        length = array == null ? 0 : array.length;
	
	    while (++index < length) {
	      if (!predicate(array[index], index, array)) {
	        return false;
	      }
	    }
	    return true;
	  }
	
	  /**
	   * A specialized version of `_.filter` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @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 = -1,
	        length = array == null ? 0 : array.length,
	        resIndex = 0,
	        result = [];
	
	    while (++index < length) {
	      var value = array[index];
	      if (predicate(value, index, array)) {
	        result[resIndex++] = value;
	      }
	    }
	    return result;
	  }
	
	  /**
	   * A specialized version of `_.includes` for arrays without support for
	   * specifying an index to search from.
	   *
	   * @private
	   * @param {Array} [array] The array to inspect.
	   * @param {*} target The value to search for.
	   * @returns {boolean} Returns `true` if `target` is found, else `false`.
	   */
	  function arrayIncludes(array, value) {
	    var length = array == null ? 0 : array.length;
	    return !!length && baseIndexOf(array, value, 0) > -1;
	  }
	
	  /**
	   * This function is like `arrayIncludes` except that it accepts a comparator.
	   *
	   * @private
	   * @param {Array} [array] The array to inspect.
	   * @param {*} target The value to search for.
	   * @param {Function} comparator The comparator invoked per element.
	   * @returns {boolean} Returns `true` if `target` is found, else `false`.
	   */
	  function arrayIncludesWith(array, value, comparator) {
	    var index = -1,
	        length = array == null ? 0 : array.length;
	
	    while (++index < length) {
	      if (comparator(value, array[index])) {
	        return true;
	      }
	    }
	    return false;
	  }
	
	  /**
	   * A specialized version of `_.map` for arrays without support for iteratee
	   * shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {Array} Returns the new mapped array.
	   */
	  function arrayMap(array, iteratee) {
	    var index = -1,
	        length = array == null ? 0 : array.length,
	        result = Array(length);
	
	    while (++index < length) {
	      result[index] = iteratee(array[index], index, array);
	    }
	    return result;
	  }
	
	  /**
	   * Appends the elements of `values` to `array`.
	   *
	   * @private
	   * @param {Array} array The array to modify.
	   * @param {Array} values The values to append.
	   * @returns {Array} Returns `array`.
	   */
	  function arrayPush(array, values) {
	    var index = -1,
	        length = values.length,
	        offset = array.length;
	
	    while (++index < length) {
	      array[offset + index] = values[index];
	    }
	    return array;
	  }
	
	  /**
	   * A specialized version of `_.reduce` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @param {*} [accumulator] The initial value.
	   * @param {boolean} [initAccum] Specify using the first element of `array` as
	   *  the initial value.
	   * @returns {*} Returns the accumulated value.
	   */
	  function arrayReduce(array, iteratee, accumulator, initAccum) {
	    var index = -1,
	        length = array == null ? 0 : array.length;
	
	    if (initAccum && length) {
	      accumulator = array[++index];
	    }
	    while (++index < length) {
	      accumulator = iteratee(accumulator, array[index], index, array);
	    }
	    return accumulator;
	  }
	
	  /**
	   * A specialized version of `_.reduceRight` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @param {*} [accumulator] The initial value.
	   * @param {boolean} [initAccum] Specify using the last element of `array` as
	   *  the initial value.
	   * @returns {*} Returns the accumulated value.
	   */
	  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
	    var length = array == null ? 0 : array.length;
	    if (initAccum && length) {
	      accumulator = array[--length];
	    }
	    while (length--) {
	      accumulator = iteratee(accumulator, array[length], length, array);
	    }
	    return accumulator;
	  }
	
	  /**
	   * A specialized version of `_.some` for arrays without support for iteratee
	   * shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} predicate The function invoked per iteration.
	   * @returns {boolean} Returns `true` if any element passes the predicate check,
	   *  else `false`.
	   */
	  function arraySome(array, predicate) {
	    var index = -1,
	        length = array == null ? 0 : array.length;
	
	    while (++index < length) {
	      if (predicate(array[index], index, array)) {
	        return true;
	      }
	    }
	    return false;
	  }
	
	  /**
	   * Gets the size of an ASCII `string`.
	   *
	   * @private
	   * @param {string} string The string inspect.
	   * @returns {number} Returns the string size.
	   */
	  var asciiSize = baseProperty('length');
	
	  /**
	   * Converts an ASCII `string` to an array.
	   *
	   * @private
	   * @param {string} string The string to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function asciiToArray(string) {
	    return string.split('');
	  }
	
	  /**
	   * Splits an ASCII `string` into an array of its words.
	   *
	   * @private
	   * @param {string} The string to inspect.
	   * @returns {Array} Returns the words of `string`.
	   */
	  function asciiWords(string) {
	    return string.match(reAsciiWord) || [];
	  }
	
	  /**
	   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
	   * without support for iteratee shorthands, which iterates over `collection`
	   * using `eachFunc`.
	   *
	   * @private
	   * @param {Array|Object} collection The collection to inspect.
	   * @param {Function} predicate The function invoked per iteration.
	   * @param {Function} eachFunc The function to iterate over `collection`.
	   * @returns {*} Returns the found element or its key, else `undefined`.
	   */
	  function baseFindKey(collection, predicate, eachFunc) {
	    var result;
	    eachFunc(collection, function(value, key, collection) {
	      if (predicate(value, key, collection)) {
	        result = key;
	        return false;
	      }
	    });
	    return result;
	  }
	
	  /**
	   * The base implementation of `_.findIndex` and `_.findLastIndex` without
	   * support for iteratee shorthands.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {Function} predicate The function invoked per iteration.
	   * @param {number} fromIndex The index to search from.
	   * @param {boolean} [fromRight] Specify iterating from right to left.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function baseFindIndex(array, predicate, fromIndex, fromRight) {
	    var length = array.length,
	        index = fromIndex + (fromRight ? 1 : -1);
	
	    while ((fromRight ? index-- : ++index < length)) {
	      if (predicate(array[index], index, array)) {
	        return index;
	      }
	    }
	    return -1;
	  }
	
	  /**
	   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function baseIndexOf(array, value, fromIndex) {
	    return value === value
	      ? strictIndexOf(array, value, fromIndex)
	      : baseFindIndex(array, baseIsNaN, fromIndex);
	  }
	
	  /**
	   * This function is like `baseIndexOf` except that it accepts a comparator.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @param {Function} comparator The comparator invoked per element.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function baseIndexOfWith(array, value, fromIndex, comparator) {
	    var index = fromIndex - 1,
	        length = array.length;
	
	    while (++index < length) {
	      if (comparator(array[index], value)) {
	        return index;
	      }
	    }
	    return -1;
	  }
	
	  /**
	   * The base implementation of `_.isNaN` without support for number objects.
	   *
	   * @private
	   * @param {*} value The value to check.
	   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
	   */
	  function baseIsNaN(value) {
	    return value !== value;
	  }
	
	  /**
	   * The base implementation of `_.mean` and `_.meanBy` without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} array The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {number} Returns the mean.
	   */
	  function baseMean(array, iteratee) {
	    var length = array == null ? 0 : array.length;
	    return length ? (baseSum(array, iteratee) / length) : NAN;
	  }
	
	  /**
	   * The base implementation of `_.property` without support for deep paths.
	   *
	   * @private
	   * @param {string} key The key of the property to get.
	   * @returns {Function} Returns the new accessor function.
	   */
	  function baseProperty(key) {
	    return function(object) {
	      return object == null ? undefined : object[key];
	    };
	  }
	
	  /**
	   * The base implementation of `_.propertyOf` without support for deep paths.
	   *
	   * @private
	   * @param {Object} object The object to query.
	   * @returns {Function} Returns the new accessor function.
	   */
	  function basePropertyOf(object) {
	    return function(key) {
	      return object == null ? undefined : object[key];
	    };
	  }
	
	  /**
	   * The base implementation of `_.reduce` and `_.reduceRight`, without support
	   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
	   *
	   * @private
	   * @param {Array|Object} collection The collection to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @param {*} accumulator The initial value.
	   * @param {boolean} initAccum Specify using the first or last element of
	   *  `collection` as the initial value.
	   * @param {Function} eachFunc The function to iterate over `collection`.
	   * @returns {*} Returns the accumulated value.
	   */
	  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
	    eachFunc(collection, function(value, index, collection) {
	      accumulator = initAccum
	        ? (initAccum = false, value)
	        : iteratee(accumulator, value, index, collection);
	    });
	    return accumulator;
	  }
	
	  /**
	   * The base implementation of `_.sortBy` which uses `comparer` to define the
	   * sort order of `array` and replaces criteria objects with their corresponding
	   * values.
	   *
	   * @private
	   * @param {Array} array The array to sort.
	   * @param {Function} comparer The function to define sort order.
	   * @returns {Array} Returns `array`.
	   */
	  function baseSortBy(array, comparer) {
	    var length = array.length;
	
	    array.sort(comparer);
	    while (length--) {
	      array[length] = array[length].value;
	    }
	    return array;
	  }
	
	  /**
	   * The base implementation of `_.sum` and `_.sumBy` without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} array The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {number} Returns the sum.
	   */
	  function baseSum(array, iteratee) {
	    var result,
	        index = -1,
	        length = array.length;
	
	    while (++index < length) {
	      var current = iteratee(array[index]);
	      if (current !== undefined) {
	        result = result === undefined ? current : (result + current);
	      }
	    }
	    return result;
	  }
	
	  /**
	   * The base implementation of `_.times` without support for iteratee shorthands
	   * or max array length checks.
	   *
	   * @private
	   * @param {number} n The number of times to invoke `iteratee`.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {Array} Returns the array of results.
	   */
	  function baseTimes(n, iteratee) {
	    var index = -1,
	        result = Array(n);
	
	    while (++index < n) {
	      result[index] = iteratee(index);
	    }
	    return result;
	  }
	
	  /**
	   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
	   * of key-value pairs for `object` corresponding to the property names of `props`.
	   *
	   * @private
	   * @param {Object} object The object to query.
	   * @param {Array} props The property names to get values for.
	   * @returns {Object} Returns the key-value pairs.
	   */
	  function baseToPairs(object, props) {
	    return arrayMap(props, function(key) {
	      return [key, object[key]];
	    });
	  }
	
	  /**
	   * The base implementation of `_.unary` without support for storing metadata.
	   *
	   * @private
	   * @param {Function} func The function to cap arguments for.
	   * @returns {Function} Returns the new capped function.
	   */
	  function baseUnary(func) {
	    return function(value) {
	      return func(value);
	    };
	  }
	
	  /**
	   * The base implementation of `_.values` and `_.valuesIn` which creates an
	   * array of `object` property values corresponding to the property names
	   * of `props`.
	   *
	   * @private
	   * @param {Object} object The object to query.
	   * @param {Array} props The property names to get values for.
	   * @returns {Object} Returns the array of property values.
	   */
	  function baseValues(object, props) {
	    return arrayMap(props, function(key) {
	      return object[key];
	    });
	  }
	
	  /**
	   * Checks if a `cache` value for `key` exists.
	   *
	   * @private
	   * @param {Object} cache The cache to query.
	   * @param {string} key The key of the entry to check.
	   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	   */
	  function cacheHas(cache, key) {
	    return cache.has(key);
	  }
	
	  /**
	   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
	   * that is not found in the character symbols.
	   *
	   * @private
	   * @param {Array} strSymbols The string symbols to inspect.
	   * @param {Array} chrSymbols The character symbols to find.
	   * @returns {number} Returns the index of the first unmatched string symbol.
	   */
	  function charsStartIndex(strSymbols, chrSymbols) {
	    var index = -1,
	        length = strSymbols.length;
	
	    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
	    return index;
	  }
	
	  /**
	   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
	   * that is not found in the character symbols.
	   *
	   * @private
	   * @param {Array} strSymbols The string symbols to inspect.
	   * @param {Array} chrSymbols The character symbols to find.
	   * @returns {number} Returns the index of the last unmatched string symbol.
	   */
	  function charsEndIndex(strSymbols, chrSymbols) {
	    var index = strSymbols.length;
	
	    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
	    return index;
	  }
	
	  /**
	   * Gets the number of `placeholder` occurrences in `array`.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} placeholder The placeholder to search for.
	   * @returns {number} Returns the placeholder count.
	   */
	  function countHolders(array, placeholder) {
	    var length = array.length,
	        result = 0;
	
	    while (length--) {
	      if (array[length] === placeholder) {
	        ++result;
	      }
	    }
	    return result;
	  }
	
	  /**
	   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
	   * letters to basic Latin letters.
	   *
	   * @private
	   * @param {string} letter The matched letter to deburr.
	   * @returns {string} Returns the deburred letter.
	   */
	  var deburrLetter = basePropertyOf(deburredLetters);
	
	  /**
	   * Used by `_.escape` to convert characters to HTML entities.
	   *
	   * @private
	   * @param {string} chr The matched character to escape.
	   * @returns {string} Returns the escaped character.
	   */
	  var escapeHtmlChar = basePropertyOf(htmlEscapes);
	
	  /**
	   * Used by `_.template` to escape characters for inclusion in compiled string literals.
	   *
	   * @private
	   * @param {string} chr The matched character to escape.
	   * @returns {string} Returns the escaped character.
	   */
	  function escapeStringChar(chr) {
	    return '\\' + stringEscapes[chr];
	  }
	
	  /**
	   * Gets the value at `key` of `object`.
	   *
	   * @private
	   * @param {Object} [object] The object to query.
	   * @param {string} key The key of the property to get.
	   * @returns {*} Returns the property value.
	   */
	  function getValue(object, key) {
	    return object == null ? undefined : object[key];
	  }
	
	  /**
	   * Checks if `string` contains Unicode symbols.
	   *
	   * @private
	   * @param {string} string The string to inspect.
	   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
	   */
	  function hasUnicode(string) {
	    return reHasUnicode.test(string);
	  }
	
	  /**
	   * Checks if `string` contains a word composed of Unicode symbols.
	   *
	   * @private
	   * @param {string} string The string to inspect.
	   * @returns {boolean} Returns `true` if a word is found, else `false`.
	   */
	  function hasUnicodeWord(string) {
	    return reHasUnicodeWord.test(string);
	  }
	
	  /**
	   * Converts `iterator` to an array.
	   *
	   * @private
	   * @param {Object} iterator The iterator to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function iteratorToArray(iterator) {
	    var data,
	        result = [];
	
	    while (!(data = iterator.next()).done) {
	      result.push(data.value);
	    }
	    return result;
	  }
	
	  /**
	   * Converts `map` to its key-value pairs.
	   *
	   * @private
	   * @param {Object} map The map to convert.
	   * @returns {Array} Returns the key-value pairs.
	   */
	  function mapToArray(map) {
	    var index = -1,
	        result = Array(map.size);
	
	    map.forEach(function(value, key) {
	      result[++index] = [key, value];
	    });
	    return result;
	  }
	
	  /**
	   * Creates a unary function that invokes `func` with its argument transformed.
	   *
	   * @private
	   * @param {Function} func The function to wrap.
	   * @param {Function} transform The argument transform.
	   * @returns {Function} Returns the new function.
	   */
	  function overArg(func, transform) {
	    return function(arg) {
	      return func(transform(arg));
	    };
	  }
	
	  /**
	   * Replaces all `placeholder` elements in `array` with an internal placeholder
	   * and returns an array of their indexes.
	   *
	   * @private
	   * @param {Array} array The array to modify.
	   * @param {*} placeholder The placeholder to replace.
	   * @returns {Array} Returns the new array of placeholder indexes.
	   */
	  function replaceHolders(array, placeholder) {
	    var index = -1,
	        length = array.length,
	        resIndex = 0,
	        result = [];
	
	    while (++index < length) {
	      var value = array[index];
	      if (value === placeholder || value === PLACEHOLDER) {
	        array[index] = PLACEHOLDER;
	        result[resIndex++] = index;
	      }
	    }
	    return result;
	  }
	
	  /**
	   * Converts `set` to an array of its values.
	   *
	   * @private
	   * @param {Object} set The set to convert.
	   * @returns {Array} Returns the values.
	   */
	  function setToArray(set) {
	    var index = -1,
	        result = Array(set.size);
	
	    set.forEach(function(value) {
	      result[++index] = value;
	    });
	    return result;
	  }
	
	  /**
	   * Converts `set` to its value-value pairs.
	   *
	   * @private
	   * @param {Object} set The set to convert.
	   * @returns {Array} Returns the value-value pairs.
	   */
	  function setToPairs(set) {
	    var index = -1,
	        result = Array(set.size);
	
	    set.forEach(function(value) {
	      result[++index] = [value, value];
	    });
	    return result;
	  }
	
	  /**
	   * A specialized version of `_.indexOf` which performs strict equality
	   * comparisons of values, i.e. `===`.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function strictIndexOf(array, value, fromIndex) {
	    var index = fromIndex - 1,
	        length = array.length;
	
	    while (++index < length) {
	      if (array[index] === value) {
	        return index;
	      }
	    }
	    return -1;
	  }
	
	  /**
	   * A specialized version of `_.lastIndexOf` which performs strict equality
	   * comparisons of values, i.e. `===`.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function strictLastIndexOf(array, value, fromIndex) {
	    var index = fromIndex + 1;
	    while (index--) {
	      if (array[index] === value) {
	        return index;
	      }
	    }
	    return index;
	  }
	
	  /**
	   * Gets the number of symbols in `string`.
	   *
	   * @private
	   * @param {string} string The string to inspect.
	   * @returns {number} Returns the string size.
	   */
	  function stringSize(string) {
	    return hasUnicode(string)
	      ? unicodeSize(string)
	      : asciiSize(string);
	  }
	
	  /**
	   * Converts `string` to an array.
	   *
	   * @private
	   * @param {string} string The string to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function stringToArray(string) {
	    return hasUnicode(string)
	      ? unicodeToArray(string)
	      : asciiToArray(string);
	  }
	
	  /**
	   * Used by `_.unescape` to convert HTML entities to characters.
	   *
	   * @private
	   * @param {string} chr The matched character to unescape.
	   * @returns {string} Returns the unescaped character.
	   */
	  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
	
	  /**
	   * Gets the size of a Unicode `string`.
	   *
	   * @private
	   * @param {string} string The string inspect.
	   * @returns {number} Returns the string size.
	   */
	  function unicodeSize(string) {
	    var result = reUnicode.lastIndex = 0;
	    while (reUnicode.test(string)) {
	      ++result;
	    }
	    return result;
	  }
	
	  /**
	   * Converts a Unicode `string` to an array.
	   *
	   * @private
	   * @param {string} string The string to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function unicodeToArray(string) {
	    return string.match(reUnicode) || [];
	  }
	
	  /**
	   * Splits a Unicode `string` into an array of its words.
	   *
	   * @private
	   * @param {string} The string to inspect.
	   * @returns {Array} Returns the words of `string`.
	   */
	  function unicodeWords(string) {
	    return string.match(reUnicodeWord) || [];
	  }
	
	  /*--------------------------------------------------------------------------*/
	
	  /**
	   * Create a new pristine `lodash` function using the `context` object.
	   *
	   * @static
	   * @memberOf _
	   * @since 1.1.0
	   * @category Util
	   * @param {Object} [context=root] The context object.
	   * @returns {Function} Returns a new `lodash` function.
	   * @example
	   *
	   * _.mixin({ 'foo': _.constant('foo') });
	   *
	   * var lodash = _.runInContext();
	   * lodash.mixin({ 'bar': lodash.constant('bar') });
	   *
	   * _.isFunction(_.foo);
	   * // => true
	   * _.isFunction(_.bar);
	   * // => false
	   *
	   * lodash.isFunction(lodash.foo);
	   * // => false
	   * lodash.isFunction(lodash.bar);
	   * // => true
	   *
	   * // Create a suped-up `defer` in Node.js.
	   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
	   */
	  var runInContext = (function runInContext(context) {
	    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
	
	    /** Built-in constructor references. */
	    var Array = context.Array,
	        Date = context.Date,
	        Error = context.Error,
	        Function = context.Function,
	        Math = context.Math,
	        Object = context.Object,
	        RegExp = context.RegExp,
	        String = context.String,
	        TypeError = context.TypeError;
	
	    /** Used for built-in method references. */
	    var arrayProto = Array.prototype,
	        funcProto = Function.prototype,
	        objectProto = Object.prototype;
	
	    /** Used to detect overreaching core-js shims. */
	    var coreJsData = context['__core-js_shared__'];
	
	    /** Used to resolve the decompiled source of functions. */
	    var funcToString = funcProto.toString;
	
	    /** Used to check objects for own properties. */
	    var hasOwnProperty = objectProto.hasOwnProperty;
	
	    /** Used to generate unique IDs. */
	    var idCounter = 0;
	
	    /** Used to detect methods masquerading as native. */
	    var maskSrcKey = (function() {
	      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
	      return uid ? ('Symbol(src)_1.' + uid) : '';
	    }());
	
	    /**
	     * Used to resolve the
	     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	     * of values.
	     */
	    var nativeObjectToString = objectProto.toString;
	
	    /** Used to infer the `Object` constructor. */
	    var objectCtorString = funcToString.call(Object);
	
	    /** Used to restore the original `_` reference in `_.noConflict`. */
	    var oldDash = root._;
	
	    /** Used to detect if a method is native. */
	    var reIsNative = RegExp('^' +
	      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
	      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
	    );
	
	    /** Built-in value references. */
	    var Buffer = moduleExports ? context.Buffer : undefined,
	        Symbol = context.Symbol,
	        Uint8Array = context.Uint8Array,
	        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
	        getPrototype = overArg(Object.getPrototypeOf, Object),
	        objectCreate = Object.create,
	        propertyIsEnumerable = objectProto.propertyIsEnumerable,
	        splice = arrayProto.splice,
	        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
	        symIterator = Symbol ? Symbol.iterator : undefined,
	        symToStringTag = Symbol ? Symbol.toStringTag : undefined;
	
	    var defineProperty = (function() {
	      try {
	        var func = getNative(Object, 'defineProperty');
	        func({}, '', {});
	        return func;
	      } catch (e) {}
	    }());
	
	    /** Mocked built-ins. */
	    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
	        ctxNow = Date && Date.now !== root.Date.now && Date.now,
	        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
	
	    /* Built-in method references for those with the same name as other `lodash` methods. */
	    var nativeCeil = Math.ceil,
	        nativeFloor = Math.floor,
	        nativeGetSymbols = Object.getOwnPropertySymbols,
	        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
	        nativeIsFinite = context.isFinite,
	        nativeJoin = arrayProto.join,
	        nativeKeys = overArg(Object.keys, Object),
	        nativeMax = Math.max,
	        nativeMin = Math.min,
	        nativeNow = Date.now,
	        nativeParseInt = context.parseInt,
	        nativeRandom = Math.random,
	        nativeReverse = arrayProto.reverse;
	
	    /* Built-in method references that are verified to be native. */
	    var DataView = getNative(context, 'DataView'),
	        Map = getNative(context, 'Map'),
	        Promise = getNative(context, 'Promise'),
	        Set = getNative(context, 'Set'),
	        WeakMap = getNative(context, 'WeakMap'),
	        nativeCreate = getNative(Object, 'create');
	
	    /** Used to store function metadata. */
	    var metaMap = WeakMap && new WeakMap;
	
	    /** Used to lookup unminified function names. */
	    var realNames = {};
	
	    /** Used to detect maps, sets, and weakmaps. */
	    var dataViewCtorString = toSource(DataView),
	        mapCtorString = toSource(Map),
	        promiseCtorString = toSource(Promise),
	        setCtorString = toSource(Set),
	        weakMapCtorString = toSource(WeakMap);
	
	    /** Used to convert symbols to primitives and strings. */
	    var symbolProto = Symbol ? Symbol.prototype : undefined,
	        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
	        symbolToString = symbolProto ? symbolProto.toString : undefined;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a `lodash` object which wraps `value` to enable implicit method
	     * chain sequences. Methods that operate on and return arrays, collections,
	     * and functions can be chained together. Methods that retrieve a single value
	     * or may return a primitive value will automatically end the chain sequence
	     * and return the unwrapped value. Otherwise, the value must be unwrapped
	     * with `_#value`.
	     *
	     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
	     * enabled using `_.chain`.
	     *
	     * The execution of chained methods is lazy, that is, it's deferred until
	     * `_#value` is implicitly or explicitly called.
	     *
	     * Lazy evaluation allows several methods to support shortcut fusion.
	     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
	     * the creation of intermediate arrays and can greatly reduce the number of
	     * iteratee executions. Sections of a chain sequence qualify for shortcut
	     * fusion if the section is applied to an array and iteratees accept only
	     * one argument. The heuristic for whether a section qualifies for shortcut
	     * fusion is subject to change.
	     *
	     * Chaining is supported in custom builds as long as the `_#value` method is
	     * directly or indirectly included in the build.
	     *
	     * In addition to lodash methods, wrappers have `Array` and `String` methods.
	     *
	     * The wrapper `Array` methods are:
	     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
	     *
	     * The wrapper `String` methods are:
	     * `replace` and `split`
	     *
	     * The wrapper methods that support shortcut fusion are:
	     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
	     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
	     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
	     *
	     * The chainable wrapper methods are:
	     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
	     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
	     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
	     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
	     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
	     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
	     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
	     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
	     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
	     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
	     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
	     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
	     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
	     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
	     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
	     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
	     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
	     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
	     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
	     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
	     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
	     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
	     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
	     * `zipObject`, `zipObjectDeep`, and `zipWith`
	     *
	     * The wrapper methods that are **not** chainable by default are:
	     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
	     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
	     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
	     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
	     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
	     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
	     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
	     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
	     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
	     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
	     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
	     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
	     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
	     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
	     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
	     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
	     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
	     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
	     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
	     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
	     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
	     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
	     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
	     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
	     * `upperFirst`, `value`, and `words`
	     *
	     * @name _
	     * @constructor
	     * @category Seq
	     * @param {*} value The value to wrap in a `lodash` instance.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var wrapped = _([1, 2, 3]);
	     *
	     * // Returns an unwrapped value.
	     * wrapped.reduce(_.add);
	     * // => 6
	     *
	     * // Returns a wrapped value.
	     * var squares = wrapped.map(square);
	     *
	     * _.isArray(squares);
	     * // => false
	     *
	     * _.isArray(squares.value());
	     * // => true
	     */
	    function lodash(value) {
	      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
	        if (value instanceof LodashWrapper) {
	          return value;
	        }
	        if (hasOwnProperty.call(value, '__wrapped__')) {
	          return wrapperClone(value);
	        }
	      }
	      return new LodashWrapper(value);
	    }
	
	    /**
	     * The base implementation of `_.create` without support for assigning
	     * properties to the created object.
	     *
	     * @private
	     * @param {Object} proto The object to inherit from.
	     * @returns {Object} Returns the new object.
	     */
	    var baseCreate = (function() {
	      function object() {}
	      return function(proto) {
	        if (!isObject(proto)) {
	          return {};
	        }
	        if (objectCreate) {
	          return objectCreate(proto);
	        }
	        object.prototype = proto;
	        var result = new object;
	        object.prototype = undefined;
	        return result;
	      };
	    }());
	
	    /**
	     * The function whose prototype chain sequence wrappers inherit from.
	     *
	     * @private
	     */
	    function baseLodash() {
	      // No operation performed.
	    }
	
	    /**
	     * The base constructor for creating `lodash` wrapper objects.
	     *
	     * @private
	     * @param {*} value The value to wrap.
	     * @param {boolean} [chainAll] Enable explicit method chain sequences.
	     */
	    function LodashWrapper(value, chainAll) {
	      this.__wrapped__ = value;
	      this.__actions__ = [];
	      this.__chain__ = !!chainAll;
	      this.__index__ = 0;
	      this.__values__ = undefined;
	    }
	
	    /**
	     * By default, the template delimiters used by lodash are like those in
	     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
	     * following template settings to use alternative delimiters.
	     *
	     * @static
	     * @memberOf _
	     * @type {Object}
	     */
	    lodash.templateSettings = {
	
	      /**
	       * Used to detect `data` property values to be HTML-escaped.
	       *
	       * @memberOf _.templateSettings
	       * @type {RegExp}
	       */
	      'escape': reEscape,
	
	      /**
	       * Used to detect code to be evaluated.
	       *
	       * @memberOf _.templateSettings
	       * @type {RegExp}
	       */
	      'evaluate': reEvaluate,
	
	      /**
	       * Used to detect `data` property values to inject.
	       *
	       * @memberOf _.templateSettings
	       * @type {RegExp}
	       */
	      'interpolate': reInterpolate,
	
	      /**
	       * Used to reference the data object in the template text.
	       *
	       * @memberOf _.templateSettings
	       * @type {string}
	       */
	      'variable': '',
	
	      /**
	       * Used to import variables into the compiled template.
	       *
	       * @memberOf _.templateSettings
	       * @type {Object}
	       */
	      'imports': {
	
	        /**
	         * A reference to the `lodash` function.
	         *
	         * @memberOf _.templateSettings.imports
	         * @type {Function}
	         */
	        '_': lodash
	      }
	    };
	
	    // Ensure wrappers are instances of `baseLodash`.
	    lodash.prototype = baseLodash.prototype;
	    lodash.prototype.constructor = lodash;
	
	    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
	    LodashWrapper.prototype.constructor = LodashWrapper;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
	     *
	     * @private
	     * @constructor
	     * @param {*} value The value to wrap.
	     */
	    function LazyWrapper(value) {
	      this.__wrapped__ = value;
	      this.__actions__ = [];
	      this.__dir__ = 1;
	      this.__filtered__ = false;
	      this.__iteratees__ = [];
	      this.__takeCount__ = MAX_ARRAY_LENGTH;
	      this.__views__ = [];
	    }
	
	    /**
	     * Creates a clone of the lazy wrapper object.
	     *
	     * @private
	     * @name clone
	     * @memberOf LazyWrapper
	     * @returns {Object} Returns the cloned `LazyWrapper` object.
	     */
	    function lazyClone() {
	      var result = new LazyWrapper(this.__wrapped__);
	      result.__actions__ = copyArray(this.__actions__);
	      result.__dir__ = this.__dir__;
	      result.__filtered__ = this.__filtered__;
	      result.__iteratees__ = copyArray(this.__iteratees__);
	      result.__takeCount__ = this.__takeCount__;
	      result.__views__ = copyArray(this.__views__);
	      return result;
	    }
	
	    /**
	     * Reverses the direction of lazy iteration.
	     *
	     * @private
	     * @name reverse
	     * @memberOf LazyWrapper
	     * @returns {Object} Returns the new reversed `LazyWrapper` object.
	     */
	    function lazyReverse() {
	      if (this.__filtered__) {
	        var result = new LazyWrapper(this);
	        result.__dir__ = -1;
	        result.__filtered__ = true;
	      } else {
	        result = this.clone();
	        result.__dir__ *= -1;
	      }
	      return result;
	    }
	
	    /**
	     * Extracts the unwrapped value from its lazy wrapper.
	     *
	     * @private
	     * @name value
	     * @memberOf LazyWrapper
	     * @returns {*} Returns the unwrapped value.
	     */
	    function lazyValue() {
	      var array = this.__wrapped__.value(),
	          dir = this.__dir__,
	          isArr = isArray(array),
	          isRight = dir < 0,
	          arrLength = isArr ? array.length : 0,
	          view = getView(0, arrLength, this.__views__),
	          start = view.start,
	          end = view.end,
	          length = end - start,
	          index = isRight ? end : (start - 1),
	          iteratees = this.__iteratees__,
	          iterLength = iteratees.length,
	          resIndex = 0,
	          takeCount = nativeMin(length, this.__takeCount__);
	
	      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
	        return baseWrapperValue(array, this.__actions__);
	      }
	      var result = [];
	
	      outer:
	      while (length-- && resIndex < takeCount) {
	        index += dir;
	
	        var iterIndex = -1,
	            value = array[index];
	
	        while (++iterIndex < iterLength) {
	          var data = iteratees[iterIndex],
	              iteratee = data.iteratee,
	              type = data.type,
	              computed = iteratee(value);
	
	          if (type == LAZY_MAP_FLAG) {
	            value = computed;
	          } else if (!computed) {
	            if (type == LAZY_FILTER_FLAG) {
	              continue outer;
	            } else {
	              break outer;
	            }
	          }
	        }
	        result[resIndex++] = value;
	      }
	      return result;
	    }
	
	    // Ensure `LazyWrapper` is an instance of `baseLodash`.
	    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
	    LazyWrapper.prototype.constructor = LazyWrapper;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a hash object.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [entries] The key-value pairs to cache.
	     */
	    function Hash(entries) {
	      var index = -1,
	          length = entries == null ? 0 : entries.length;
	
	      this.clear();
	      while (++index < length) {
	        var entry = entries[index];
	        this.set(entry[0], entry[1]);
	      }
	    }
	
	    /**
	     * Removes all key-value entries from the hash.
	     *
	     * @private
	     * @name clear
	     * @memberOf Hash
	     */
	    function hashClear() {
	      this.__data__ = nativeCreate ? nativeCreate(null) : {};
	      this.size = 0;
	    }
	
	    /**
	     * Removes `key` and its value from the hash.
	     *
	     * @private
	     * @name delete
	     * @memberOf Hash
	     * @param {Object} hash The hash to modify.
	     * @param {string} key The key of the value to remove.
	     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	     */
	    function hashDelete(key) {
	      var result = this.has(key) && delete this.__data__[key];
	      this.size -= result ? 1 : 0;
	      return result;
	    }
	
	    /**
	     * Gets the hash value for `key`.
	     *
	     * @private
	     * @name get
	     * @memberOf Hash
	     * @param {string} key The key of the value to get.
	     * @returns {*} Returns the entry value.
	     */
	    function hashGet(key) {
	      var data = this.__data__;
	      if (nativeCreate) {
	        var result = data[key];
	        return result === HASH_UNDEFINED ? undefined : result;
	      }
	      return hasOwnProperty.call(data, key) ? data[key] : undefined;
	    }
	
	    /**
	     * Checks if a hash value for `key` exists.
	     *
	     * @private
	     * @name has
	     * @memberOf Hash
	     * @param {string} key The key of the entry to check.
	     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	     */
	    function hashHas(key) {
	      var data = this.__data__;
	      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
	    }
	
	    /**
	     * Sets the hash `key` to `value`.
	     *
	     * @private
	     * @name set
	     * @memberOf Hash
	     * @param {string} key The key of the value to set.
	     * @param {*} value The value to set.
	     * @returns {Object} Returns the hash instance.
	     */
	    function hashSet(key, value) {
	      var data = this.__data__;
	      this.size += this.has(key) ? 0 : 1;
	      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
	      return this;
	    }
	
	    // Add methods to `Hash`.
	    Hash.prototype.clear = hashClear;
	    Hash.prototype['delete'] = hashDelete;
	    Hash.prototype.get = hashGet;
	    Hash.prototype.has = hashHas;
	    Hash.prototype.set = hashSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an list cache object.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [entries] The key-value pairs to cache.
	     */
	    function ListCache(entries) {
	      var index = -1,
	          length = entries == null ? 0 : entries.length;
	
	      this.clear();
	      while (++index < length) {
	        var entry = entries[index];
	        this.set(entry[0], entry[1]);
	      }
	    }
	
	    /**
	     * Removes all key-value entries from the list cache.
	     *
	     * @private
	     * @name clear
	     * @memberOf ListCache
	     */
	    function listCacheClear() {
	      this.__data__ = [];
	      this.size = 0;
	    }
	
	    /**
	     * Removes `key` and its value from the list cache.
	     *
	     * @private
	     * @name delete
	     * @memberOf ListCache
	     * @param {string} key The key of the value to remove.
	     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	     */
	    function listCacheDelete(key) {
	      var data = this.__data__,
	          index = assocIndexOf(data, key);
	
	      if (index < 0) {
	        return false;
	      }
	      var lastIndex = data.length - 1;
	      if (index == lastIndex) {
	        data.pop();
	      } else {
	        splice.call(data, index, 1);
	      }
	      --this.size;
	      return true;
	    }
	
	    /**
	     * Gets the list cache value for `key`.
	     *
	     * @private
	     * @name get
	     * @memberOf ListCache
	     * @param {string} key The key of the value to get.
	     * @returns {*} Returns the entry value.
	     */
	    function listCacheGet(key) {
	      var data = this.__data__,
	          index = assocIndexOf(data, key);
	
	      return index < 0 ? undefined : data[index][1];
	    }
	
	    /**
	     * Checks if a list cache value for `key` exists.
	     *
	     * @private
	     * @name has
	     * @memberOf ListCache
	     * @param {string} key The key of the entry to check.
	     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	     */
	    function listCacheHas(key) {
	      return assocIndexOf(this.__data__, key) > -1;
	    }
	
	    /**
	     * Sets the list cache `key` to `value`.
	     *
	     * @private
	     * @name set
	     * @memberOf ListCache
	     * @param {string} key The key of the value to set.
	     * @param {*} value The value to set.
	     * @returns {Object} Returns the list cache instance.
	     */
	    function listCacheSet(key, value) {
	      var data = this.__data__,
	          index = assocIndexOf(data, key);
	
	      if (index < 0) {
	        ++this.size;
	        data.push([key, value]);
	      } else {
	        data[index][1] = value;
	      }
	      return this;
	    }
	
	    // Add methods to `ListCache`.
	    ListCache.prototype.clear = listCacheClear;
	    ListCache.prototype['delete'] = listCacheDelete;
	    ListCache.prototype.get = listCacheGet;
	    ListCache.prototype.has = listCacheHas;
	    ListCache.prototype.set = listCacheSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a map cache object to store key-value pairs.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [entries] The key-value pairs to cache.
	     */
	    function MapCache(entries) {
	      var index = -1,
	          length = entries == null ? 0 : entries.length;
	
	      this.clear();
	      while (++index < length) {
	        var entry = entries[index];
	        this.set(entry[0], entry[1]);
	      }
	    }
	
	    /**
	     * Removes all key-value entries from the map.
	     *
	     * @private
	     * @name clear
	     * @memberOf MapCache
	     */
	    function mapCacheClear() {
	      this.size = 0;
	      this.__data__ = {
	        'hash': new Hash,
	        'map': new (Map || ListCache),
	        'string': new Hash
	      };
	    }
	
	    /**
	     * Removes `key` and its value from the map.
	     *
	     * @private
	     * @name delete
	     * @memberOf MapCache
	     * @param {string} key The key of the value to remove.
	     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	     */
	    function mapCacheDelete(key) {
	      var result = getMapData(this, key)['delete'](key);
	      this.size -= result ? 1 : 0;
	      return result;
	    }
	
	    /**
	     * Gets the map value for `key`.
	     *
	     * @private
	     * @name get
	     * @memberOf MapCache
	     * @param {string} key The key of the value to get.
	     * @returns {*} Returns the entry value.
	     */
	    function mapCacheGet(key) {
	      return getMapData(this, key).get(key);
	    }
	
	    /**
	     * Checks if a map value for `key` exists.
	     *
	     * @private
	     * @name has
	     * @memberOf MapCache
	     * @param {string} key The key of the entry to check.
	     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	     */
	    function mapCacheHas(key) {
	      return getMapData(this, key).has(key);
	    }
	
	    /**
	     * Sets the map `key` to `value`.
	     *
	     * @private
	     * @name set
	     * @memberOf MapCache
	     * @param {string} key The key of the value to set.
	     * @param {*} value The value to set.
	     * @returns {Object} Returns the map cache instance.
	     */
	    function mapCacheSet(key, value) {
	      var data = getMapData(this, key),
	          size = data.size;
	
	      data.set(key, value);
	      this.size += data.size == size ? 0 : 1;
	      return this;
	    }
	
	    // Add methods to `MapCache`.
	    MapCache.prototype.clear = mapCacheClear;
	    MapCache.prototype['delete'] = mapCacheDelete;
	    MapCache.prototype.get = mapCacheGet;
	    MapCache.prototype.has = mapCacheHas;
	    MapCache.prototype.set = mapCacheSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     *
	     * Creates an array cache object to store unique values.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [values] The values to cache.
	     */
	    function SetCache(values) {
	      var index = -1,
	          length = values == null ? 0 : values.length;
	
	      this.__data__ = new MapCache;
	      while (++index < length) {
	        this.add(values[index]);
	      }
	    }
	
	    /**
	     * Adds `value` to the array cache.
	     *
	     * @private
	     * @name add
	     * @memberOf SetCache
	     * @alias push
	     * @param {*} value The value to cache.
	     * @returns {Object} Returns the cache instance.
	     */
	    function setCacheAdd(value) {
	      this.__data__.set(value, HASH_UNDEFINED);
	      return this;
	    }
	
	    /**
	     * Checks if `value` is in the array cache.
	     *
	     * @private
	     * @name has
	     * @memberOf SetCache
	     * @param {*} value The value to search for.
	     * @returns {number} Returns `true` if `value` is found, else `false`.
	     */
	    function setCacheHas(value) {
	      return this.__data__.has(value);
	    }
	
	    // Add methods to `SetCache`.
	    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
	    SetCache.prototype.has = setCacheHas;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a stack cache object to store key-value pairs.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [entries] The key-value pairs to cache.
	     */
	    function Stack(entries) {
	      var data = this.__data__ = new ListCache(entries);
	      this.size = data.size;
	    }
	
	    /**
	     * Removes all key-value entries from the stack.
	     *
	     * @private
	     * @name clear
	     * @memberOf Stack
	     */
	    function stackClear() {
	      this.__data__ = new ListCache;
	      this.size = 0;
	    }
	
	    /**
	     * Removes `key` and its value from the stack.
	     *
	     * @private
	     * @name delete
	     * @memberOf Stack
	     * @param {string} key The key of the value to remove.
	     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	     */
	    function stackDelete(key) {
	      var data = this.__data__,
	          result = data['delete'](key);
	
	      this.size = data.size;
	      return result;
	    }
	
	    /**
	     * Gets the stack value for `key`.
	     *
	     * @private
	     * @name get
	     * @memberOf Stack
	     * @param {string} key The key of the value to get.
	     * @returns {*} Returns the entry value.
	     */
	    function stackGet(key) {
	      return this.__data__.get(key);
	    }
	
	    /**
	     * Checks if a stack value for `key` exists.
	     *
	     * @private
	     * @name has
	     * @memberOf Stack
	     * @param {string} key The key of the entry to check.
	     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	     */
	    function stackHas(key) {
	      return this.__data__.has(key);
	    }
	
	    /**
	     * Sets the stack `key` to `value`.
	     *
	     * @private
	     * @name set
	     * @memberOf Stack
	     * @param {string} key The key of the value to set.
	     * @param {*} value The value to set.
	     * @returns {Object} Returns the stack cache instance.
	     */
	    function stackSet(key, value) {
	      var data = this.__data__;
	      if (data instanceof ListCache) {
	        var pairs = data.__data__;
	        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
	          pairs.push([key, value]);
	          this.size = ++data.size;
	          return this;
	        }
	        data = this.__data__ = new MapCache(pairs);
	      }
	      data.set(key, value);
	      this.size = data.size;
	      return this;
	    }
	
	    // Add methods to `Stack`.
	    Stack.prototype.clear = stackClear;
	    Stack.prototype['delete'] = stackDelete;
	    Stack.prototype.get = stackGet;
	    Stack.prototype.has = stackHas;
	    Stack.prototype.set = stackSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an array of the enumerable property names of the array-like `value`.
	     *
	     * @private
	     * @param {*} value The value to query.
	     * @param {boolean} inherited Specify returning inherited property names.
	     * @returns {Array} Returns the array of property names.
	     */
	    function arrayLikeKeys(value, inherited) {
	      var isArr = isArray(value),
	          isArg = !isArr && isArguments(value),
	          isBuff = !isArr && !isArg && isBuffer(value),
	          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
	          skipIndexes = isArr || isArg || isBuff || isType,
	          result = skipIndexes ? baseTimes(value.length, String) : [],
	          length = result.length;
	
	      for (var key in value) {
	        if ((inherited || hasOwnProperty.call(value, key)) &&
	            !(skipIndexes && (
	               // Safari 9 has enumerable `arguments.length` in strict mode.
	               key == 'length' ||
	               // Node.js 0.10 has enumerable non-index properties on buffers.
	               (isBuff && (key == 'offset' || key == 'parent')) ||
	               // PhantomJS 2 has enumerable non-index properties on typed arrays.
	               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
	               // Skip index properties.
	               isIndex(key, length)
	            ))) {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * A specialized version of `_.sample` for arrays.
	     *
	     * @private
	     * @param {Array} array The array to sample.
	     * @returns {*} Returns the random element.
	     */
	    function arraySample(array) {
	      var length = array.length;
	      return length ? array[baseRandom(0, length - 1)] : undefined;
	    }
	
	    /**
	     * A specialized version of `_.sampleSize` for arrays.
	     *
	     * @private
	     * @param {Array} array The array to sample.
	     * @param {number} n The number of elements to sample.
	     * @returns {Array} Returns the random elements.
	     */
	    function arraySampleSize(array, n) {
	      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
	    }
	
	    /**
	     * A specialized version of `_.shuffle` for arrays.
	     *
	     * @private
	     * @param {Array} array The array to shuffle.
	     * @returns {Array} Returns the new shuffled array.
	     */
	    function arrayShuffle(array) {
	      return shuffleSelf(copyArray(array));
	    }
	
	    /**
	     * This function is like `assignValue` except that it doesn't assign
	     * `undefined` values.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {string} key The key of the property to assign.
	     * @param {*} value The value to assign.
	     */
	    function assignMergeValue(object, key, value) {
	      if ((value !== undefined && !eq(object[key], value)) ||
	          (value === undefined && !(key in object))) {
	        baseAssignValue(object, key, value);
	      }
	    }
	
	    /**
	     * Assigns `value` to `key` of `object` if the existing value is not equivalent
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {string} key The key of the property to assign.
	     * @param {*} value The value to assign.
	     */
	    function assignValue(object, key, value) {
	      var objValue = object[key];
	      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
	          (value === undefined && !(key in object))) {
	        baseAssignValue(object, key, value);
	      }
	    }
	
	    /**
	     * Gets the index at which the `key` is found in `array` of key-value pairs.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {*} key The key to search for.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     */
	    function assocIndexOf(array, key) {
	      var length = array.length;
	      while (length--) {
	        if (eq(array[length][0], key)) {
	          return length;
	        }
	      }
	      return -1;
	    }
	
	    /**
	     * Aggregates elements of `collection` on `accumulator` with keys transformed
	     * by `iteratee` and values set by `setter`.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} setter The function to set `accumulator` values.
	     * @param {Function} iteratee The iteratee to transform keys.
	     * @param {Object} accumulator The initial aggregated object.
	     * @returns {Function} Returns `accumulator`.
	     */
	    function baseAggregator(collection, setter, iteratee, accumulator) {
	      baseEach(collection, function(value, key, collection) {
	        setter(accumulator, value, iteratee(value), collection);
	      });
	      return accumulator;
	    }
	
	    /**
	     * The base implementation of `_.assign` without support for multiple sources
	     * or `customizer` functions.
	     *
	     * @private
	     * @param {Object} object The destination object.
	     * @param {Object} source The source object.
	     * @returns {Object} Returns `object`.
	     */
	    function baseAssign(object, source) {
	      return object && copyObject(source, keys(source), object);
	    }
	
	    /**
	     * The base implementation of `_.assignIn` without support for multiple sources
	     * or `customizer` functions.
	     *
	     * @private
	     * @param {Object} object The destination object.
	     * @param {Object} source The source object.
	     * @returns {Object} Returns `object`.
	     */
	    function baseAssignIn(object, source) {
	      return object && copyObject(source, keysIn(source), object);
	    }
	
	    /**
	     * The base implementation of `assignValue` and `assignMergeValue` without
	     * value checks.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {string} key The key of the property to assign.
	     * @param {*} value The value to assign.
	     */
	    function baseAssignValue(object, key, value) {
	      if (key == '__proto__' && defineProperty) {
	        defineProperty(object, key, {
	          'configurable': true,
	          'enumerable': true,
	          'value': value,
	          'writable': true
	        });
	      } else {
	        object[key] = value;
	      }
	    }
	
	    /**
	     * The base implementation of `_.at` without support for individual paths.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {string[]} paths The property paths to pick.
	     * @returns {Array} Returns the picked elements.
	     */
	    function baseAt(object, paths) {
	      var index = -1,
	          length = paths.length,
	          result = Array(length),
	          skip = object == null;
	
	      while (++index < length) {
	        result[index] = skip ? undefined : get(object, paths[index]);
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.clamp` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {number} number The number to clamp.
	     * @param {number} [lower] The lower bound.
	     * @param {number} upper The upper bound.
	     * @returns {number} Returns the clamped number.
	     */
	    function baseClamp(number, lower, upper) {
	      if (number === number) {
	        if (upper !== undefined) {
	          number = number <= upper ? number : upper;
	        }
	        if (lower !== undefined) {
	          number = number >= lower ? number : lower;
	        }
	      }
	      return number;
	    }
	
	    /**
	     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
	     * traversed objects.
	     *
	     * @private
	     * @param {*} value The value to clone.
	     * @param {boolean} bitmask The bitmask flags.
	     *  1 - Deep clone
	     *  2 - Flatten inherited properties
	     *  4 - Clone symbols
	     * @param {Function} [customizer] The function to customize cloning.
	     * @param {string} [key] The key of `value`.
	     * @param {Object} [object] The parent object of `value`.
	     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
	     * @returns {*} Returns the cloned value.
	     */
	    function baseClone(value, bitmask, customizer, key, object, stack) {
	      var result,
	          isDeep = bitmask & CLONE_DEEP_FLAG,
	          isFlat = bitmask & CLONE_FLAT_FLAG,
	          isFull = bitmask & CLONE_SYMBOLS_FLAG;
	
	      if (customizer) {
	        result = object ? customizer(value, key, object, stack) : customizer(value);
	      }
	      if (result !== undefined) {
	        return result;
	      }
	      if (!isObject(value)) {
	        return value;
	      }
	      var isArr = isArray(value);
	      if (isArr) {
	        result = initCloneArray(value);
	        if (!isDeep) {
	          return copyArray(value, result);
	        }
	      } else {
	        var tag = getTag(value),
	            isFunc = tag == funcTag || tag == genTag;
	
	        if (isBuffer(value)) {
	          return cloneBuffer(value, isDeep);
	        }
	        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
	          result = (isFlat || isFunc) ? {} : initCloneObject(value);
	          if (!isDeep) {
	            return isFlat
	              ? copySymbolsIn(value, baseAssignIn(result, value))
	              : copySymbols(value, baseAssign(result, value));
	          }
	        } else {
	          if (!cloneableTags[tag]) {
	            return object ? value : {};
	          }
	          result = initCloneByTag(value, tag, baseClone, isDeep);
	        }
	      }
	      // Check for circular references and return its corresponding clone.
	      stack || (stack = new Stack);
	      var stacked = stack.get(value);
	      if (stacked) {
	        return stacked;
	      }
	      stack.set(value, result);
	
	      var keysFunc = isFull
	        ? (isFlat ? getAllKeysIn : getAllKeys)
	        : (isFlat ? keysIn : keys);
	
	      var props = isArr ? undefined : keysFunc(value);
	      arrayEach(props || value, function(subValue, key) {
	        if (props) {
	          key = subValue;
	          subValue = value[key];
	        }
	        // Recursively populate clone (susceptible to call stack limits).
	        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.conforms` which doesn't clone `source`.
	     *
	     * @private
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {Function} Returns the new spec function.
	     */
	    function baseConforms(source) {
	      var props = keys(source);
	      return function(object) {
	        return baseConformsTo(object, source, props);
	      };
	    }
	
	    /**
	     * The base implementation of `_.conformsTo` which accepts `props` to check.
	     *
	     * @private
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
	     */
	    function baseConformsTo(object, source, props) {
	      var length = props.length;
	      if (object == null) {
	        return !length;
	      }
	      object = Object(object);
	      while (length--) {
	        var key = props[length],
	            predicate = source[key],
	            value = object[key];
	
	        if ((value === undefined && !(key in object)) || !predicate(value)) {
	          return false;
	        }
	      }
	      return true;
	    }
	
	    /**
	     * The base implementation of `_.delay` and `_.defer` which accepts `args`
	     * to provide to `func`.
	     *
	     * @private
	     * @param {Function} func The function to delay.
	     * @param {number} wait The number of milliseconds to delay invocation.
	     * @param {Array} args The arguments to provide to `func`.
	     * @returns {number|Object} Returns the timer id or timeout object.
	     */
	    function baseDelay(func, wait, args) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      return setTimeout(function() { func.apply(undefined, args); }, wait);
	    }
	
	    /**
	     * The base implementation of methods like `_.difference` without support
	     * for excluding multiple arrays or iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {Array} values The values to exclude.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     */
	    function baseDifference(array, values, iteratee, comparator) {
	      var index = -1,
	          includes = arrayIncludes,
	          isCommon = true,
	          length = array.length,
	          result = [],
	          valuesLength = values.length;
	
	      if (!length) {
	        return result;
	      }
	      if (iteratee) {
	        values = arrayMap(values, baseUnary(iteratee));
	      }
	      if (comparator) {
	        includes = arrayIncludesWith;
	        isCommon = false;
	      }
	      else if (values.length >= LARGE_ARRAY_SIZE) {
	        includes = cacheHas;
	        isCommon = false;
	        values = new SetCache(values);
	      }
	      outer:
	      while (++index < length) {
	        var value = array[index],
	            computed = iteratee == null ? value : iteratee(value);
	
	        value = (comparator || value !== 0) ? value : 0;
	        if (isCommon && computed === computed) {
	          var valuesIndex = valuesLength;
	          while (valuesIndex--) {
	            if (values[valuesIndex] === computed) {
	              continue outer;
	            }
	          }
	          result.push(value);
	        }
	        else if (!includes(values, computed, comparator)) {
	          result.push(value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.forEach` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     */
	    var baseEach = createBaseEach(baseForOwn);
	
	    /**
	     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     */
	    var baseEachRight = createBaseEach(baseForOwnRight, true);
	
	    /**
	     * The base implementation of `_.every` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} predicate The function invoked per iteration.
	     * @returns {boolean} Returns `true` if all elements pass the predicate check,
	     *  else `false`
	     */
	    function baseEvery(collection, predicate) {
	      var result = true;
	      baseEach(collection, function(value, index, collection) {
	        result = !!predicate(value, index, collection);
	        return result;
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of methods like `_.max` and `_.min` which accepts a
	     * `comparator` to determine the extremum value.
	     *
	     * @private
	     * @param {Array} array The array to iterate over.
	     * @param {Function} iteratee The iteratee invoked per iteration.
	     * @param {Function} comparator The comparator used to compare values.
	     * @returns {*} Returns the extremum value.
	     */
	    function baseExtremum(array, iteratee, comparator) {
	      var index = -1,
	          length = array.length;
	
	      while (++index < length) {
	        var value = array[index],
	            current = iteratee(value);
	
	        if (current != null && (computed === undefined
	              ? (current === current && !isSymbol(current))
	              : comparator(current, computed)
	            )) {
	          var computed = current,
	              result = value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.fill` without an iteratee call guard.
	     *
	     * @private
	     * @param {Array} array The array to fill.
	     * @param {*} value The value to fill `array` with.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns `array`.
	     */
	    function baseFill(array, value, start, end) {
	      var length = array.length;
	
	      start = toInteger(start);
	      if (start < 0) {
	        start = -start > length ? 0 : (length + start);
	      }
	      end = (end === undefined || end > length) ? length : toInteger(end);
	      if (end < 0) {
	        end += length;
	      }
	      end = start > end ? 0 : toLength(end);
	      while (start < end) {
	        array[start++] = value;
	      }
	      return array;
	    }
	
	    /**
	     * The base implementation of `_.filter` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} predicate The function invoked per iteration.
	     * @returns {Array} Returns the new filtered array.
	     */
	    function baseFilter(collection, predicate) {
	      var result = [];
	      baseEach(collection, function(value, index, collection) {
	        if (predicate(value, index, collection)) {
	          result.push(value);
	        }
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.flatten` with support for restricting flattening.
	     *
	     * @private
	     * @param {Array} array The array to flatten.
	     * @param {number} depth The maximum recursion depth.
	     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
	     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
	     * @param {Array} [result=[]] The initial result value.
	     * @returns {Array} Returns the new flattened array.
	     */
	    function baseFlatten(array, depth, predicate, isStrict, result) {
	      var index = -1,
	          length = array.length;
	
	      predicate || (predicate = isFlattenable);
	      result || (result = []);
	
	      while (++index < length) {
	        var value = array[index];
	        if (depth > 0 && predicate(value)) {
	          if (depth > 1) {
	            // Recursively flatten arrays (susceptible to call stack limits).
	            baseFlatten(value, depth - 1, predicate, isStrict, result);
	          } else {
	            arrayPush(result, value);
	          }
	        } else if (!isStrict) {
	          result[result.length] = value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `baseForOwn` which iterates over `object`
	     * properties returned by `keysFunc` and invokes `iteratee` for each property.
	     * Iteratee functions may exit iteration early by explicitly returning `false`.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @param {Function} keysFunc The function to get the keys of `object`.
	     * @returns {Object} Returns `object`.
	     */
	    var baseFor = createBaseFor();
	
	    /**
	     * This function is like `baseFor` except that it iterates over properties
	     * in the opposite order.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @param {Function} keysFunc The function to get the keys of `object`.
	     * @returns {Object} Returns `object`.
	     */
	    var baseForRight = createBaseFor(true);
	
	    /**
	     * The base implementation of `_.forOwn` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     */
	    function baseForOwn(object, iteratee) {
	      return object && baseFor(object, iteratee, keys);
	    }
	
	    /**
	     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     */
	    function baseForOwnRight(object, iteratee) {
	      return object && baseForRight(object, iteratee, keys);
	    }
	
	    /**
	     * The base implementation of `_.functions` which creates an array of
	     * `object` function property names filtered from `props`.
	     *
	     * @private
	     * @param {Object} object The object to inspect.
	     * @param {Array} props The property names to filter.
	     * @returns {Array} Returns the function names.
	     */
	    function baseFunctions(object, props) {
	      return arrayFilter(props, function(key) {
	        return isFunction(object[key]);
	      });
	    }
	
	    /**
	     * The base implementation of `_.get` without support for default values.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the property to get.
	     * @returns {*} Returns the resolved value.
	     */
	    function baseGet(object, path) {
	      path = castPath(path, object);
	
	      var index = 0,
	          length = path.length;
	
	      while (object != null && index < length) {
	        object = object[toKey(path[index++])];
	      }
	      return (index && index == length) ? object : undefined;
	    }
	
	    /**
	     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
	     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
	     * symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Function} keysFunc The function to get the keys of `object`.
	     * @param {Function} symbolsFunc The function to get the symbols of `object`.
	     * @returns {Array} Returns the array of property names and symbols.
	     */
	    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
	      var result = keysFunc(object);
	      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
	    }
	
	    /**
	     * The base implementation of `getTag` without fallbacks for buggy environments.
	     *
	     * @private
	     * @param {*} value The value to query.
	     * @returns {string} Returns the `toStringTag`.
	     */
	    function baseGetTag(value) {
	      if (value == null) {
	        return value === undefined ? undefinedTag : nullTag;
	      }
	      return (symToStringTag && symToStringTag in Object(value))
	        ? getRawTag(value)
	        : objectToString(value);
	    }
	
	    /**
	     * The base implementation of `_.gt` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is greater than `other`,
	     *  else `false`.
	     */
	    function baseGt(value, other) {
	      return value > other;
	    }
	
	    /**
	     * The base implementation of `_.has` without support for deep paths.
	     *
	     * @private
	     * @param {Object} [object] The object to query.
	     * @param {Array|string} key The key to check.
	     * @returns {boolean} Returns `true` if `key` exists, else `false`.
	     */
	    function baseHas(object, key) {
	      return object != null && hasOwnProperty.call(object, key);
	    }
	
	    /**
	     * The base implementation of `_.hasIn` without support for deep paths.
	     *
	     * @private
	     * @param {Object} [object] The object to query.
	     * @param {Array|string} key The key to check.
	     * @returns {boolean} Returns `true` if `key` exists, else `false`.
	     */
	    function baseHasIn(object, key) {
	      return object != null && key in Object(object);
	    }
	
	    /**
	     * The base implementation of `_.inRange` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {number} number The number to check.
	     * @param {number} start The start of the range.
	     * @param {number} end The end of the range.
	     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
	     */
	    function baseInRange(number, start, end) {
	      return number >= nativeMin(start, end) && number < nativeMax(start, end);
	    }
	
	    /**
	     * The base implementation of methods like `_.intersection`, without support
	     * for iteratee shorthands, that accepts an array of arrays to inspect.
	     *
	     * @private
	     * @param {Array} arrays The arrays to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of shared values.
	     */
	    function baseIntersection(arrays, iteratee, comparator) {
	      var includes = comparator ? arrayIncludesWith : arrayIncludes,
	          length = arrays[0].length,
	          othLength = arrays.length,
	          othIndex = othLength,
	          caches = Array(othLength),
	          maxLength = Infinity,
	          result = [];
	
	      while (othIndex--) {
	        var array = arrays[othIndex];
	        if (othIndex && iteratee) {
	          array = arrayMap(array, baseUnary(iteratee));
	        }
	        maxLength = nativeMin(array.length, maxLength);
	        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
	          ? new SetCache(othIndex && array)
	          : undefined;
	      }
	      array = arrays[0];
	
	      var index = -1,
	          seen = caches[0];
	
	      outer:
	      while (++index < length && result.length < maxLength) {
	        var value = array[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        value = (comparator || value !== 0) ? value : 0;
	        if (!(seen
	              ? cacheHas(seen, computed)
	              : includes(result, computed, comparator)
	            )) {
	          othIndex = othLength;
	          while (--othIndex) {
	            var cache = caches[othIndex];
	            if (!(cache
	                  ? cacheHas(cache, computed)
	                  : includes(arrays[othIndex], computed, comparator))
	                ) {
	              continue outer;
	            }
	          }
	          if (seen) {
	            seen.push(computed);
	          }
	          result.push(value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.invert` and `_.invertBy` which inverts
	     * `object` with values transformed by `iteratee` and set by `setter`.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} setter The function to set `accumulator` values.
	     * @param {Function} iteratee The iteratee to transform values.
	     * @param {Object} accumulator The initial inverted object.
	     * @returns {Function} Returns `accumulator`.
	     */
	    function baseInverter(object, setter, iteratee, accumulator) {
	      baseForOwn(object, function(value, key, object) {
	        setter(accumulator, iteratee(value), key, object);
	      });
	      return accumulator;
	    }
	
	    /**
	     * The base implementation of `_.invoke` without support for individual
	     * method arguments.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the method to invoke.
	     * @param {Array} args The arguments to invoke the method with.
	     * @returns {*} Returns the result of the invoked method.
	     */
	    function baseInvoke(object, path, args) {
	      path = castPath(path, object);
	      object = parent(object, path);
	      var func = object == null ? object : object[toKey(last(path))];
	      return func == null ? undefined : apply(func, object, args);
	    }
	
	    /**
	     * The base implementation of `_.isArguments`.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	     */
	    function baseIsArguments(value) {
	      return isObjectLike(value) && baseGetTag(value) == argsTag;
	    }
	
	    /**
	     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
	     */
	    function baseIsArrayBuffer(value) {
	      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
	    }
	
	    /**
	     * The base implementation of `_.isDate` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
	     */
	    function baseIsDate(value) {
	      return isObjectLike(value) && baseGetTag(value) == dateTag;
	    }
	
	    /**
	     * The base implementation of `_.isEqual` which supports partial comparisons
	     * and tracks traversed objects.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @param {boolean} bitmask The bitmask flags.
	     *  1 - Unordered comparison
	     *  2 - Partial comparison
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
	     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	     */
	    function baseIsEqual(value, other, bitmask, customizer, stack) {
	      if (value === other) {
	        return true;
	      }
	      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
	        return value !== value && other !== other;
	      }
	      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
	    }
	
	    /**
	     * A specialized version of `baseIsEqual` for arrays and objects which performs
	     * deep comparisons and tracks traversed objects enabling objects with circular
	     * references to be compared.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	     * @param {Function} customizer The function to customize comparisons.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
	     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	     */
	    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
	      var objIsArr = isArray(object),
	          othIsArr = isArray(other),
	          objTag = objIsArr ? arrayTag : getTag(object),
	          othTag = othIsArr ? arrayTag : getTag(other);
	
	      objTag = objTag == argsTag ? objectTag : objTag;
	      othTag = othTag == argsTag ? objectTag : othTag;
	
	      var objIsObj = objTag == objectTag,
	          othIsObj = othTag == objectTag,
	          isSameTag = objTag == othTag;
	
	      if (isSameTag && isBuffer(object)) {
	        if (!isBuffer(other)) {
	          return false;
	        }
	        objIsArr = true;
	        objIsObj = false;
	      }
	      if (isSameTag && !objIsObj) {
	        stack || (stack = new Stack);
	        return (objIsArr || isTypedArray(object))
	          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
	          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
	      }
	      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
	        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
	            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
	
	        if (objIsWrapped || othIsWrapped) {
	          var objUnwrapped = objIsWrapped ? object.value() : object,
	              othUnwrapped = othIsWrapped ? other.value() : other;
	
	          stack || (stack = new Stack);
	          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
	        }
	      }
	      if (!isSameTag) {
	        return false;
	      }
	      stack || (stack = new Stack);
	      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
	    }
	
	    /**
	     * The base implementation of `_.isMap` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
	     */
	    function baseIsMap(value) {
	      return isObjectLike(value) && getTag(value) == mapTag;
	    }
	
	    /**
	     * The base implementation of `_.isMatch` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property values to match.
	     * @param {Array} matchData The property names, values, and compare flags to match.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
	     */
	    function baseIsMatch(object, source, matchData, customizer) {
	      var index = matchData.length,
	          length = index,
	          noCustomizer = !customizer;
	
	      if (object == null) {
	        return !length;
	      }
	      object = Object(object);
	      while (index--) {
	        var data = matchData[index];
	        if ((noCustomizer && data[2])
	              ? data[1] !== object[data[0]]
	              : !(data[0] in object)
	            ) {
	          return false;
	        }
	      }
	      while (++index < length) {
	        data = matchData[index];
	        var key = data[0],
	            objValue = object[key],
	            srcValue = data[1];
	
	        if (noCustomizer && data[2]) {
	          if (objValue === undefined && !(key in object)) {
	            return false;
	          }
	        } else {
	          var stack = new Stack;
	          if (customizer) {
	            var result = customizer(objValue, srcValue, key, object, source, stack);
	          }
	          if (!(result === undefined
	                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
	                : result
	              )) {
	            return false;
	          }
	        }
	      }
	      return true;
	    }
	
	    /**
	     * The base implementation of `_.isNative` without bad shim checks.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a native function,
	     *  else `false`.
	     */
	    function baseIsNative(value) {
	      if (!isObject(value) || isMasked(value)) {
	        return false;
	      }
	      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
	      return pattern.test(toSource(value));
	    }
	
	    /**
	     * The base implementation of `_.isRegExp` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
	     */
	    function baseIsRegExp(value) {
	      return isObjectLike(value) && baseGetTag(value) == regexpTag;
	    }
	
	    /**
	     * The base implementation of `_.isSet` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
	     */
	    function baseIsSet(value) {
	      return isObjectLike(value) && getTag(value) == setTag;
	    }
	
	    /**
	     * The base implementation of `_.isTypedArray` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	     */
	    function baseIsTypedArray(value) {
	      return isObjectLike(value) &&
	        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
	    }
	
	    /**
	     * The base implementation of `_.iteratee`.
	     *
	     * @private
	     * @param {*} [value=_.identity] The value to convert to an iteratee.
	     * @returns {Function} Returns the iteratee.
	     */
	    function baseIteratee(value) {
	      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
	      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
	      if (typeof value == 'function') {
	        return value;
	      }
	      if (value == null) {
	        return identity;
	      }
	      if (typeof value == 'object') {
	        return isArray(value)
	          ? baseMatchesProperty(value[0], value[1])
	          : baseMatches(value);
	      }
	      return property(value);
	    }
	
	    /**
	     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     */
	    function baseKeys(object) {
	      if (!isPrototype(object)) {
	        return nativeKeys(object);
	      }
	      var result = [];
	      for (var key in Object(object)) {
	        if (hasOwnProperty.call(object, key) && key != 'constructor') {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     */
	    function baseKeysIn(object) {
	      if (!isObject(object)) {
	        return nativeKeysIn(object);
	      }
	      var isProto = isPrototype(object),
	          result = [];
	
	      for (var key in object) {
	        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.lt` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is less than `other`,
	     *  else `false`.
	     */
	    function baseLt(value, other) {
	      return value < other;
	    }
	
	    /**
	     * The base implementation of `_.map` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Array} Returns the new mapped array.
	     */
	    function baseMap(collection, iteratee) {
	      var index = -1,
	          result = isArrayLike(collection) ? Array(collection.length) : [];
	
	      baseEach(collection, function(value, key, collection) {
	        result[++index] = iteratee(value, key, collection);
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.matches` which doesn't clone `source`.
	     *
	     * @private
	     * @param {Object} source The object of property values to match.
	     * @returns {Function} Returns the new spec function.
	     */
	    function baseMatches(source) {
	      var matchData = getMatchData(source);
	      if (matchData.length == 1 && matchData[0][2]) {
	        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
	      }
	      return function(object) {
	        return object === source || baseIsMatch(object, source, matchData);
	      };
	    }
	
	    /**
	     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
	     *
	     * @private
	     * @param {string} path The path of the property to get.
	     * @param {*} srcValue The value to match.
	     * @returns {Function} Returns the new spec function.
	     */
	    function baseMatchesProperty(path, srcValue) {
	      if (isKey(path) && isStrictComparable(srcValue)) {
	        return matchesStrictComparable(toKey(path), srcValue);
	      }
	      return function(object) {
	        var objValue = get(object, path);
	        return (objValue === undefined && objValue === srcValue)
	          ? hasIn(object, path)
	          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
	      };
	    }
	
	    /**
	     * The base implementation of `_.merge` without support for multiple sources.
	     *
	     * @private
	     * @param {Object} object The destination object.
	     * @param {Object} source The source object.
	     * @param {number} srcIndex The index of `source`.
	     * @param {Function} [customizer] The function to customize merged values.
	     * @param {Object} [stack] Tracks traversed source values and their merged
	     *  counterparts.
	     */
	    function baseMerge(object, source, srcIndex, customizer, stack) {
	      if (object === source) {
	        return;
	      }
	      baseFor(source, function(srcValue, key) {
	        if (isObject(srcValue)) {
	          stack || (stack = new Stack);
	          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
	        }
	        else {
	          var newValue = customizer
	            ? customizer(object[key], srcValue, (key + ''), object, source, stack)
	            : undefined;
	
	          if (newValue === undefined) {
	            newValue = srcValue;
	          }
	          assignMergeValue(object, key, newValue);
	        }
	      }, keysIn);
	    }
	
	    /**
	     * A specialized version of `baseMerge` for arrays and objects which performs
	     * deep merges and tracks traversed objects enabling objects with circular
	     * references to be merged.
	     *
	     * @private
	     * @param {Object} object The destination object.
	     * @param {Object} source The source object.
	     * @param {string} key The key of the value to merge.
	     * @param {number} srcIndex The index of `source`.
	     * @param {Function} mergeFunc The function to merge values.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @param {Object} [stack] Tracks traversed source values and their merged
	     *  counterparts.
	     */
	    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
	      var objValue = object[key],
	          srcValue = source[key],
	          stacked = stack.get(srcValue);
	
	      if (stacked) {
	        assignMergeValue(object, key, stacked);
	        return;
	      }
	      var newValue = customizer
	        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
	        : undefined;
	
	      var isCommon = newValue === undefined;
	
	      if (isCommon) {
	        var isArr = isArray(srcValue),
	            isBuff = !isArr && isBuffer(srcValue),
	            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
	
	        newValue = srcValue;
	        if (isArr || isBuff || isTyped) {
	          if (isArray(objValue)) {
	            newValue = objValue;
	          }
	          else if (isArrayLikeObject(objValue)) {
	            newValue = copyArray(objValue);
	          }
	          else if (isBuff) {
	            isCommon = false;
	            newValue = cloneBuffer(srcValue, true);
	          }
	          else if (isTyped) {
	            isCommon = false;
	            newValue = cloneTypedArray(srcValue, true);
	          }
	          else {
	            newValue = [];
	          }
	        }
	        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
	          newValue = objValue;
	          if (isArguments(objValue)) {
	            newValue = toPlainObject(objValue);
	          }
	          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
	            newValue = initCloneObject(srcValue);
	          }
	        }
	        else {
	          isCommon = false;
	        }
	      }
	      if (isCommon) {
	        // Recursively merge objects and arrays (susceptible to call stack limits).
	        stack.set(srcValue, newValue);
	        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
	        stack['delete'](srcValue);
	      }
	      assignMergeValue(object, key, newValue);
	    }
	
	    /**
	     * The base implementation of `_.nth` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {Array} array The array to query.
	     * @param {number} n The index of the element to return.
	     * @returns {*} Returns the nth element of `array`.
	     */
	    function baseNth(array, n) {
	      var length = array.length;
	      if (!length) {
	        return;
	      }
	      n += n < 0 ? length : 0;
	      return isIndex(n, length) ? array[n] : undefined;
	    }
	
	    /**
	     * The base implementation of `_.orderBy` without param guards.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
	     * @param {string[]} orders The sort orders of `iteratees`.
	     * @returns {Array} Returns the new sorted array.
	     */
	    function baseOrderBy(collection, iteratees, orders) {
	      var index = -1;
	      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
	
	      var result = baseMap(collection, function(value, key, collection) {
	        var criteria = arrayMap(iteratees, function(iteratee) {
	          return iteratee(value);
	        });
	        return { 'criteria': criteria, 'index': ++index, 'value': value };
	      });
	
	      return baseSortBy(result, function(object, other) {
	        return compareMultiple(object, other, orders);
	      });
	    }
	
	    /**
	     * The base implementation of `_.pick` without support for individual
	     * property identifiers.
	     *
	     * @private
	     * @param {Object} object The source object.
	     * @param {string[]} paths The property paths to pick.
	     * @returns {Object} Returns the new object.
	     */
	    function basePick(object, paths) {
	      return basePickBy(object, paths, function(value, path) {
	        return hasIn(object, path);
	      });
	    }
	
	    /**
	     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The source object.
	     * @param {string[]} paths The property paths to pick.
	     * @param {Function} predicate The function invoked per property.
	     * @returns {Object} Returns the new object.
	     */
	    function basePickBy(object, paths, predicate) {
	      var index = -1,
	          length = paths.length,
	          result = {};
	
	      while (++index < length) {
	        var path = paths[index],
	            value = baseGet(object, path);
	
	        if (predicate(value, path)) {
	          baseSet(result, castPath(path, object), value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * A specialized version of `baseProperty` which supports deep paths.
	     *
	     * @private
	     * @param {Array|string} path The path of the property to get.
	     * @returns {Function} Returns the new accessor function.
	     */
	    function basePropertyDeep(path) {
	      return function(object) {
	        return baseGet(object, path);
	      };
	    }
	
	    /**
	     * The base implementation of `_.pullAllBy` without support for iteratee
	     * shorthands.
	     *
	     * @private
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns `array`.
	     */
	    function basePullAll(array, values, iteratee, comparator) {
	      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
	          index = -1,
	          length = values.length,
	          seen = array;
	
	      if (array === values) {
	        values = copyArray(values);
	      }
	      if (iteratee) {
	        seen = arrayMap(array, baseUnary(iteratee));
	      }
	      while (++index < length) {
	        var fromIndex = 0,
	            value = values[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
	          if (seen !== array) {
	            splice.call(seen, fromIndex, 1);
	          }
	          splice.call(array, fromIndex, 1);
	        }
	      }
	      return array;
	    }
	
	    /**
	     * The base implementation of `_.pullAt` without support for individual
	     * indexes or capturing the removed elements.
	     *
	     * @private
	     * @param {Array} array The array to modify.
	     * @param {number[]} indexes The indexes of elements to remove.
	     * @returns {Array} Returns `array`.
	     */
	    function basePullAt(array, indexes) {
	      var length = array ? indexes.length : 0,
	          lastIndex = length - 1;
	
	      while (length--) {
	        var index = indexes[length];
	        if (length == lastIndex || index !== previous) {
	          var previous = index;
	          if (isIndex(index)) {
	            splice.call(array, index, 1);
	          } else {
	            baseUnset(array, index);
	          }
	        }
	      }
	      return array;
	    }
	
	    /**
	     * The base implementation of `_.random` without support for returning
	     * floating-point numbers.
	     *
	     * @private
	     * @param {number} lower The lower bound.
	     * @param {number} upper The upper bound.
	     * @returns {number} Returns the random number.
	     */
	    function baseRandom(lower, upper) {
	      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
	    }
	
	    /**
	     * The base implementation of `_.range` and `_.rangeRight` which doesn't
	     * coerce arguments.
	     *
	     * @private
	     * @param {number} start The start of the range.
	     * @param {number} end The end of the range.
	     * @param {number} step The value to increment or decrement by.
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Array} Returns the range of numbers.
	     */
	    function baseRange(start, end, step, fromRight) {
	      var index = -1,
	          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
	          result = Array(length);
	
	      while (length--) {
	        result[fromRight ? length : ++index] = start;
	        start += step;
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.repeat` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {string} string The string to repeat.
	     * @param {number} n The number of times to repeat the string.
	     * @returns {string} Returns the repeated string.
	     */
	    function baseRepeat(string, n) {
	      var result = '';
	      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
	        return result;
	      }
	      // Leverage the exponentiation by squaring algorithm for a faster repeat.
	      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
	      do {
	        if (n % 2) {
	          result += string;
	        }
	        n = nativeFloor(n / 2);
	        if (n) {
	          string += string;
	        }
	      } while (n);
	
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
	     *
	     * @private
	     * @param {Function} func The function to apply a rest parameter to.
	     * @param {number} [start=func.length-1] The start position of the rest parameter.
	     * @returns {Function} Returns the new function.
	     */
	    function baseRest(func, start) {
	      return setToString(overRest(func, start, identity), func + '');
	    }
	
	    /**
	     * The base implementation of `_.sample`.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to sample.
	     * @returns {*} Returns the random element.
	     */
	    function baseSample(collection) {
	      return arraySample(values(collection));
	    }
	
	    /**
	     * The base implementation of `_.sampleSize` without param guards.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to sample.
	     * @param {number} n The number of elements to sample.
	     * @returns {Array} Returns the random elements.
	     */
	    function baseSampleSize(collection, n) {
	      var array = values(collection);
	      return shuffleSelf(array, baseClamp(n, 0, array.length));
	    }
	
	    /**
	     * The base implementation of `_.set`.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {*} value The value to set.
	     * @param {Function} [customizer] The function to customize path creation.
	     * @returns {Object} Returns `object`.
	     */
	    function baseSet(object, path, value, customizer) {
	      if (!isObject(object)) {
	        return object;
	      }
	      path = castPath(path, object);
	
	      var index = -1,
	          length = path.length,
	          lastIndex = length - 1,
	          nested = object;
	
	      while (nested != null && ++index < length) {
	        var key = toKey(path[index]),
	            newValue = value;
	
	        if (index != lastIndex) {
	          var objValue = nested[key];
	          newValue = customizer ? customizer(objValue, key, nested) : undefined;
	          if (newValue === undefined) {
	            newValue = isObject(objValue)
	              ? objValue
	              : (isIndex(path[index + 1]) ? [] : {});
	          }
	        }
	        assignValue(nested, key, newValue);
	        nested = nested[key];
	      }
	      return object;
	    }
	
	    /**
	     * The base implementation of `setData` without support for hot loop shorting.
	     *
	     * @private
	     * @param {Function} func The function to associate metadata with.
	     * @param {*} data The metadata.
	     * @returns {Function} Returns `func`.
	     */
	    var baseSetData = !metaMap ? identity : function(func, data) {
	      metaMap.set(func, data);
	      return func;
	    };
	
	    /**
	     * The base implementation of `setToString` without support for hot loop shorting.
	     *
	     * @private
	     * @param {Function} func The function to modify.
	     * @param {Function} string The `toString` result.
	     * @returns {Function} Returns `func`.
	     */
	    var baseSetToString = !defineProperty ? identity : function(func, string) {
	      return defineProperty(func, 'toString', {
	        'configurable': true,
	        'enumerable': false,
	        'value': constant(string),
	        'writable': true
	      });
	    };
	
	    /**
	     * The base implementation of `_.shuffle`.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to shuffle.
	     * @returns {Array} Returns the new shuffled array.
	     */
	    function baseShuffle(collection) {
	      return shuffleSelf(values(collection));
	    }
	
	    /**
	     * The base implementation of `_.slice` without an iteratee call guard.
	     *
	     * @private
	     * @param {Array} array The array to slice.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns the slice of `array`.
	     */
	    function baseSlice(array, start, end) {
	      var index = -1,
	          length = array.length;
	
	      if (start < 0) {
	        start = -start > length ? 0 : (length + start);
	      }
	      end = end > length ? length : end;
	      if (end < 0) {
	        end += length;
	      }
	      length = start > end ? 0 : ((end - start) >>> 0);
	      start >>>= 0;
	
	      var result = Array(length);
	      while (++index < length) {
	        result[index] = array[index + start];
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.some` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} predicate The function invoked per iteration.
	     * @returns {boolean} Returns `true` if any element passes the predicate check,
	     *  else `false`.
	     */
	    function baseSome(collection, predicate) {
	      var result;
	
	      baseEach(collection, function(value, index, collection) {
	        result = predicate(value, index, collection);
	        return !result;
	      });
	      return !!result;
	    }
	
	    /**
	     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
	     * performs a binary search of `array` to determine the index at which `value`
	     * should be inserted into `array` in order to maintain its sort order.
	     *
	     * @private
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {boolean} [retHighest] Specify returning the highest qualified index.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     */
	    function baseSortedIndex(array, value, retHighest) {
	      var low = 0,
	          high = array == null ? low : array.length;
	
	      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
	        while (low < high) {
	          var mid = (low + high) >>> 1,
	              computed = array[mid];
	
	          if (computed !== null && !isSymbol(computed) &&
	              (retHighest ? (computed <= value) : (computed < value))) {
	            low = mid + 1;
	          } else {
	            high = mid;
	          }
	        }
	        return high;
	      }
	      return baseSortedIndexBy(array, value, identity, retHighest);
	    }
	
	    /**
	     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
	     * which invokes `iteratee` for `value` and each element of `array` to compute
	     * their sort ranking. The iteratee is invoked with one argument; (value).
	     *
	     * @private
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {Function} iteratee The iteratee invoked per element.
	     * @param {boolean} [retHighest] Specify returning the highest qualified index.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     */
	    function baseSortedIndexBy(array, value, iteratee, retHighest) {
	      value = iteratee(value);
	
	      var low = 0,
	          high = array == null ? 0 : array.length,
	          valIsNaN = value !== value,
	          valIsNull = value === null,
	          valIsSymbol = isSymbol(value),
	          valIsUndefined = value === undefined;
	
	      while (low < high) {
	        var mid = nativeFloor((low + high) / 2),
	            computed = iteratee(array[mid]),
	            othIsDefined = computed !== undefined,
	            othIsNull = computed === null,
	            othIsReflexive = computed === computed,
	            othIsSymbol = isSymbol(computed);
	
	        if (valIsNaN) {
	          var setLow = retHighest || othIsReflexive;
	        } else if (valIsUndefined) {
	          setLow = othIsReflexive && (retHighest || othIsDefined);
	        } else if (valIsNull) {
	          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
	        } else if (valIsSymbol) {
	          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
	        } else if (othIsNull || othIsSymbol) {
	          setLow = false;
	        } else {
	          setLow = retHighest ? (computed <= value) : (computed < value);
	        }
	        if (setLow) {
	          low = mid + 1;
	        } else {
	          high = mid;
	        }
	      }
	      return nativeMin(high, MAX_ARRAY_INDEX);
	    }
	
	    /**
	     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
	     * support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     */
	    function baseSortedUniq(array, iteratee) {
	      var index = -1,
	          length = array.length,
	          resIndex = 0,
	          result = [];
	
	      while (++index < length) {
	        var value = array[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        if (!index || !eq(computed, seen)) {
	          var seen = computed;
	          result[resIndex++] = value === 0 ? 0 : value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.toNumber` which doesn't ensure correct
	     * conversions of binary, hexadecimal, or octal string values.
	     *
	     * @private
	     * @param {*} value The value to process.
	     * @returns {number} Returns the number.
	     */
	    function baseToNumber(value) {
	      if (typeof value == 'number') {
	        return value;
	      }
	      if (isSymbol(value)) {
	        return NAN;
	      }
	      return +value;
	    }
	
	    /**
	     * The base implementation of `_.toString` which doesn't convert nullish
	     * values to empty strings.
	     *
	     * @private
	     * @param {*} value The value to process.
	     * @returns {string} Returns the string.
	     */
	    function baseToString(value) {
	      // Exit early for strings to avoid a performance hit in some environments.
	      if (typeof value == 'string') {
	        return value;
	      }
	      if (isArray(value)) {
	        // Recursively convert values (susceptible to call stack limits).
	        return arrayMap(value, baseToString) + '';
	      }
	      if (isSymbol(value)) {
	        return symbolToString ? symbolToString.call(value) : '';
	      }
	      var result = (value + '');
	      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
	    }
	
	    /**
	     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     */
	    function baseUniq(array, iteratee, comparator) {
	      var index = -1,
	          includes = arrayIncludes,
	          length = array.length,
	          isCommon = true,
	          result = [],
	          seen = result;
	
	      if (comparator) {
	        isCommon = false;
	        includes = arrayIncludesWith;
	      }
	      else if (length >= LARGE_ARRAY_SIZE) {
	        var set = iteratee ? null : createSet(array);
	        if (set) {
	          return setToArray(set);
	        }
	        isCommon = false;
	        includes = cacheHas;
	        seen = new SetCache;
	      }
	      else {
	        seen = iteratee ? [] : result;
	      }
	      outer:
	      while (++index < length) {
	        var value = array[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        value = (comparator || value !== 0) ? value : 0;
	        if (isCommon && computed === computed) {
	          var seenIndex = seen.length;
	          while (seenIndex--) {
	            if (seen[seenIndex] === computed) {
	              continue outer;
	            }
	          }
	          if (iteratee) {
	            seen.push(computed);
	          }
	          result.push(value);
	        }
	        else if (!includes(seen, computed, comparator)) {
	          if (seen !== result) {
	            seen.push(computed);
	          }
	          result.push(value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.unset`.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The property path to unset.
	     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
	     */
	    function baseUnset(object, path) {
	      path = castPath(path, object);
	      object = parent(object, path);
	      return object == null || delete object[toKey(last(path))];
	    }
	
	    /**
	     * The base implementation of `_.update`.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to update.
	     * @param {Function} updater The function to produce the updated value.
	     * @param {Function} [customizer] The function to customize path creation.
	     * @returns {Object} Returns `object`.
	     */
	    function baseUpdate(object, path, updater, customizer) {
	      return baseSet(object, path, updater(baseGet(object, path)), customizer);
	    }
	
	    /**
	     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
	     * without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to query.
	     * @param {Function} predicate The function invoked per iteration.
	     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Array} Returns the slice of `array`.
	     */
	    function baseWhile(array, predicate, isDrop, fromRight) {
	      var length = array.length,
	          index = fromRight ? length : -1;
	
	      while ((fromRight ? index-- : ++index < length) &&
	        predicate(array[index], index, array)) {}
	
	      return isDrop
	        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
	        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
	    }
	
	    /**
	     * The base implementation of `wrapperValue` which returns the result of
	     * performing a sequence of actions on the unwrapped `value`, where each
	     * successive action is supplied the return value of the previous.
	     *
	     * @private
	     * @param {*} value The unwrapped value.
	     * @param {Array} actions Actions to perform to resolve the unwrapped value.
	     * @returns {*} Returns the resolved value.
	     */
	    function baseWrapperValue(value, actions) {
	      var result = value;
	      if (result instanceof LazyWrapper) {
	        result = result.value();
	      }
	      return arrayReduce(actions, function(result, action) {
	        return action.func.apply(action.thisArg, arrayPush([result], action.args));
	      }, result);
	    }
	
	    /**
	     * The base implementation of methods like `_.xor`, without support for
	     * iteratee shorthands, that accepts an array of arrays to inspect.
	     *
	     * @private
	     * @param {Array} arrays The arrays to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of values.
	     */
	    function baseXor(arrays, iteratee, comparator) {
	      var length = arrays.length;
	      if (length < 2) {
	        return length ? baseUniq(arrays[0]) : [];
	      }
	      var index = -1,
	          result = Array(length);
	
	      while (++index < length) {
	        var array = arrays[index],
	            othIndex = -1;
	
	        while (++othIndex < length) {
	          if (othIndex != index) {
	            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
	          }
	        }
	      }
	      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
	    }
	
	    /**
	     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
	     *
	     * @private
	     * @param {Array} props The property identifiers.
	     * @param {Array} values The property values.
	     * @param {Function} assignFunc The function to assign values.
	     * @returns {Object} Returns the new object.
	     */
	    function baseZipObject(props, values, assignFunc) {
	      var index = -1,
	          length = props.length,
	          valsLength = values.length,
	          result = {};
	
	      while (++index < length) {
	        var value = index < valsLength ? values[index] : undefined;
	        assignFunc(result, props[index], value);
	      }
	      return result;
	    }
	
	    /**
	     * Casts `value` to an empty array if it's not an array like object.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @returns {Array|Object} Returns the cast array-like object.
	     */
	    function castArrayLikeObject(value) {
	      return isArrayLikeObject(value) ? value : [];
	    }
	
	    /**
	     * Casts `value` to `identity` if it's not a function.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @returns {Function} Returns cast function.
	     */
	    function castFunction(value) {
	      return typeof value == 'function' ? value : identity;
	    }
	
	    /**
	     * Casts `value` to a path array if it's not one.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @param {Object} [object] The object to query keys on.
	     * @returns {Array} Returns the cast property path array.
	     */
	    function castPath(value, object) {
	      if (isArray(value)) {
	        return value;
	      }
	      return isKey(value, object) ? [value] : stringToPath(toString(value));
	    }
	
	    /**
	     * A `baseRest` alias which can be replaced with `identity` by module
	     * replacement plugins.
	     *
	     * @private
	     * @type {Function}
	     * @param {Function} func The function to apply a rest parameter to.
	     * @returns {Function} Returns the new function.
	     */
	    var castRest = baseRest;
	
	    /**
	     * Casts `array` to a slice if it's needed.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {number} start The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns the cast slice.
	     */
	    function castSlice(array, start, end) {
	      var length = array.length;
	      end = end === undefined ? length : end;
	      return (!start && end >= length) ? array : baseSlice(array, start, end);
	    }
	
	    /**
	     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
	     *
	     * @private
	     * @param {number|Object} id The timer id or timeout object of the timer to clear.
	     */
	    var clearTimeout = ctxClearTimeout || function(id) {
	      return root.clearTimeout(id);
	    };
	
	    /**
	     * Creates a clone of  `buffer`.
	     *
	     * @private
	     * @param {Buffer} buffer The buffer to clone.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Buffer} Returns the cloned buffer.
	     */
	    function cloneBuffer(buffer, isDeep) {
	      if (isDeep) {
	        return buffer.slice();
	      }
	      var length = buffer.length,
	          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
	
	      buffer.copy(result);
	      return result;
	    }
	
	    /**
	     * Creates a clone of `arrayBuffer`.
	     *
	     * @private
	     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
	     * @returns {ArrayBuffer} Returns the cloned array buffer.
	     */
	    function cloneArrayBuffer(arrayBuffer) {
	      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
	      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
	      return result;
	    }
	
	    /**
	     * Creates a clone of `dataView`.
	     *
	     * @private
	     * @param {Object} dataView The data view to clone.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned data view.
	     */
	    function cloneDataView(dataView, isDeep) {
	      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
	      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
	    }
	
	    /**
	     * Creates a clone of `map`.
	     *
	     * @private
	     * @param {Object} map The map to clone.
	     * @param {Function} cloneFunc The function to clone values.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned map.
	     */
	    function cloneMap(map, isDeep, cloneFunc) {
	      var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
	      return arrayReduce(array, addMapEntry, new map.constructor);
	    }
	
	    /**
	     * Creates a clone of `regexp`.
	     *
	     * @private
	     * @param {Object} regexp The regexp to clone.
	     * @returns {Object} Returns the cloned regexp.
	     */
	    function cloneRegExp(regexp) {
	      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
	      result.lastIndex = regexp.lastIndex;
	      return result;
	    }
	
	    /**
	     * Creates a clone of `set`.
	     *
	     * @private
	     * @param {Object} set The set to clone.
	     * @param {Function} cloneFunc The function to clone values.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned set.
	     */
	    function cloneSet(set, isDeep, cloneFunc) {
	      var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
	      return arrayReduce(array, addSetEntry, new set.constructor);
	    }
	
	    /**
	     * Creates a clone of the `symbol` object.
	     *
	     * @private
	     * @param {Object} symbol The symbol object to clone.
	     * @returns {Object} Returns the cloned symbol object.
	     */
	    function cloneSymbol(symbol) {
	      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
	    }
	
	    /**
	     * Creates a clone of `typedArray`.
	     *
	     * @private
	     * @param {Object} typedArray The typed array to clone.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned typed array.
	     */
	    function cloneTypedArray(typedArray, isDeep) {
	      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
	      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
	    }
	
	    /**
	     * Compares values to sort them in ascending order.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {number} Returns the sort order indicator for `value`.
	     */
	    function compareAscending(value, other) {
	      if (value !== other) {
	        var valIsDefined = value !== undefined,
	            valIsNull = value === null,
	            valIsReflexive = value === value,
	            valIsSymbol = isSymbol(value);
	
	        var othIsDefined = other !== undefined,
	            othIsNull = other === null,
	            othIsReflexive = other === other,
	            othIsSymbol = isSymbol(other);
	
	        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
	            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
	            (valIsNull && othIsDefined && othIsReflexive) ||
	            (!valIsDefined && othIsReflexive) ||
	            !valIsReflexive) {
	          return 1;
	        }
	        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
	            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
	            (othIsNull && valIsDefined && valIsReflexive) ||
	            (!othIsDefined && valIsReflexive) ||
	            !othIsReflexive) {
	          return -1;
	        }
	      }
	      return 0;
	    }
	
	    /**
	     * Used by `_.orderBy` to compare multiple properties of a value to another
	     * and stable sort them.
	     *
	     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
	     * specify an order of "desc" for descending or "asc" for ascending sort order
	     * of corresponding values.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {boolean[]|string[]} orders The order to sort by for each property.
	     * @returns {number} Returns the sort order indicator for `object`.
	     */
	    function compareMultiple(object, other, orders) {
	      var index = -1,
	          objCriteria = object.criteria,
	          othCriteria = other.criteria,
	          length = objCriteria.length,
	          ordersLength = orders.length;
	
	      while (++index < length) {
	        var result = compareAscending(objCriteria[index], othCriteria[index]);
	        if (result) {
	          if (index >= ordersLength) {
	            return result;
	          }
	          var order = orders[index];
	          return result * (order == 'desc' ? -1 : 1);
	        }
	      }
	      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
	      // that causes it, under certain circumstances, to provide the same value for
	      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
	      // for more details.
	      //
	      // This also ensures a stable sort in V8 and other engines.
	      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
	      return object.index - other.index;
	    }
	
	    /**
	     * Creates an array that is the composition of partially applied arguments,
	     * placeholders, and provided arguments into a single array of arguments.
	     *
	     * @private
	     * @param {Array} args The provided arguments.
	     * @param {Array} partials The arguments to prepend to those provided.
	     * @param {Array} holders The `partials` placeholder indexes.
	     * @params {boolean} [isCurried] Specify composing for a curried function.
	     * @returns {Array} Returns the new array of composed arguments.
	     */
	    function composeArgs(args, partials, holders, isCurried) {
	      var argsIndex = -1,
	          argsLength = args.length,
	          holdersLength = holders.length,
	          leftIndex = -1,
	          leftLength = partials.length,
	          rangeLength = nativeMax(argsLength - holdersLength, 0),
	          result = Array(leftLength + rangeLength),
	          isUncurried = !isCurried;
	
	      while (++leftIndex < leftLength) {
	        result[leftIndex] = partials[leftIndex];
	      }
	      while (++argsIndex < holdersLength) {
	        if (isUncurried || argsIndex < argsLength) {
	          result[holders[argsIndex]] = args[argsIndex];
	        }
	      }
	      while (rangeLength--) {
	        result[leftIndex++] = args[argsIndex++];
	      }
	      return result;
	    }
	
	    /**
	     * This function is like `composeArgs` except that the arguments composition
	     * is tailored for `_.partialRight`.
	     *
	     * @private
	     * @param {Array} args The provided arguments.
	     * @param {Array} partials The arguments to append to those provided.
	     * @param {Array} holders The `partials` placeholder indexes.
	     * @params {boolean} [isCurried] Specify composing for a curried function.
	     * @returns {Array} Returns the new array of composed arguments.
	     */
	    function composeArgsRight(args, partials, holders, isCurried) {
	      var argsIndex = -1,
	          argsLength = args.length,
	          holdersIndex = -1,
	          holdersLength = holders.length,
	          rightIndex = -1,
	          rightLength = partials.length,
	          rangeLength = nativeMax(argsLength - holdersLength, 0),
	          result = Array(rangeLength + rightLength),
	          isUncurried = !isCurried;
	
	      while (++argsIndex < rangeLength) {
	        result[argsIndex] = args[argsIndex];
	      }
	      var offset = argsIndex;
	      while (++rightIndex < rightLength) {
	        result[offset + rightIndex] = partials[rightIndex];
	      }
	      while (++holdersIndex < holdersLength) {
	        if (isUncurried || argsIndex < argsLength) {
	          result[offset + holders[holdersIndex]] = args[argsIndex++];
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Copies the values of `source` to `array`.
	     *
	     * @private
	     * @param {Array} source The array to copy values from.
	     * @param {Array} [array=[]] The array to copy values to.
	     * @returns {Array} Returns `array`.
	     */
	    function copyArray(source, array) {
	      var index = -1,
	          length = source.length;
	
	      array || (array = Array(length));
	      while (++index < length) {
	        array[index] = source[index];
	      }
	      return array;
	    }
	
	    /**
	     * Copies properties of `source` to `object`.
	     *
	     * @private
	     * @param {Object} source The object to copy properties from.
	     * @param {Array} props The property identifiers to copy.
	     * @param {Object} [object={}] The object to copy properties to.
	     * @param {Function} [customizer] The function to customize copied values.
	     * @returns {Object} Returns `object`.
	     */
	    function copyObject(source, props, object, customizer) {
	      var isNew = !object;
	      object || (object = {});
	
	      var index = -1,
	          length = props.length;
	
	      while (++index < length) {
	        var key = props[index];
	
	        var newValue = customizer
	          ? customizer(object[key], source[key], key, object, source)
	          : undefined;
	
	        if (newValue === undefined) {
	          newValue = source[key];
	        }
	        if (isNew) {
	          baseAssignValue(object, key, newValue);
	        } else {
	          assignValue(object, key, newValue);
	        }
	      }
	      return object;
	    }
	
	    /**
	     * Copies own symbols of `source` to `object`.
	     *
	     * @private
	     * @param {Object} source The object to copy symbols from.
	     * @param {Object} [object={}] The object to copy symbols to.
	     * @returns {Object} Returns `object`.
	     */
	    function copySymbols(source, object) {
	      return copyObject(source, getSymbols(source), object);
	    }
	
	    /**
	     * Copies own and inherited symbols of `source` to `object`.
	     *
	     * @private
	     * @param {Object} source The object to copy symbols from.
	     * @param {Object} [object={}] The object to copy symbols to.
	     * @returns {Object} Returns `object`.
	     */
	    function copySymbolsIn(source, object) {
	      return copyObject(source, getSymbolsIn(source), object);
	    }
	
	    /**
	     * Creates a function like `_.groupBy`.
	     *
	     * @private
	     * @param {Function} setter The function to set accumulator values.
	     * @param {Function} [initializer] The accumulator object initializer.
	     * @returns {Function} Returns the new aggregator function.
	     */
	    function createAggregator(setter, initializer) {
	      return function(collection, iteratee) {
	        var func = isArray(collection) ? arrayAggregator : baseAggregator,
	            accumulator = initializer ? initializer() : {};
	
	        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
	      };
	    }
	
	    /**
	     * Creates a function like `_.assign`.
	     *
	     * @private
	     * @param {Function} assigner The function to assign values.
	     * @returns {Function} Returns the new assigner function.
	     */
	    function createAssigner(assigner) {
	      return baseRest(function(object, sources) {
	        var index = -1,
	            length = sources.length,
	            customizer = length > 1 ? sources[length - 1] : undefined,
	            guard = length > 2 ? sources[2] : undefined;
	
	        customizer = (assigner.length > 3 && typeof customizer == 'function')
	          ? (length--, customizer)
	          : undefined;
	
	        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
	          customizer = length < 3 ? undefined : customizer;
	          length = 1;
	        }
	        object = Object(object);
	        while (++index < length) {
	          var source = sources[index];
	          if (source) {
	            assigner(object, source, index, customizer);
	          }
	        }
	        return object;
	      });
	    }
	
	    /**
	     * Creates a `baseEach` or `baseEachRight` function.
	     *
	     * @private
	     * @param {Function} eachFunc The function to iterate over a collection.
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new base function.
	     */
	    function createBaseEach(eachFunc, fromRight) {
	      return function(collection, iteratee) {
	        if (collection == null) {
	          return collection;
	        }
	        if (!isArrayLike(collection)) {
	          return eachFunc(collection, iteratee);
	        }
	        var length = collection.length,
	            index = fromRight ? length : -1,
	            iterable = Object(collection);
	
	        while ((fromRight ? index-- : ++index < length)) {
	          if (iteratee(iterable[index], index, iterable) === false) {
	            break;
	          }
	        }
	        return collection;
	      };
	    }
	
	    /**
	     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
	     *
	     * @private
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new base function.
	     */
	    function createBaseFor(fromRight) {
	      return function(object, iteratee, keysFunc) {
	        var index = -1,
	            iterable = Object(object),
	            props = keysFunc(object),
	            length = props.length;
	
	        while (length--) {
	          var key = props[fromRight ? length : ++index];
	          if (iteratee(iterable[key], key, iterable) === false) {
	            break;
	          }
	        }
	        return object;
	      };
	    }
	
	    /**
	     * Creates a function that wraps `func` to invoke it with the optional `this`
	     * binding of `thisArg`.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createBind(func, bitmask, thisArg) {
	      var isBind = bitmask & WRAP_BIND_FLAG,
	          Ctor = createCtor(func);
	
	      function wrapper() {
	        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
	        return fn.apply(isBind ? thisArg : this, arguments);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a function like `_.lowerFirst`.
	     *
	     * @private
	     * @param {string} methodName The name of the `String` case method to use.
	     * @returns {Function} Returns the new case function.
	     */
	    function createCaseFirst(methodName) {
	      return function(string) {
	        string = toString(string);
	
	        var strSymbols = hasUnicode(string)
	          ? stringToArray(string)
	          : undefined;
	
	        var chr = strSymbols
	          ? strSymbols[0]
	          : string.charAt(0);
	
	        var trailing = strSymbols
	          ? castSlice(strSymbols, 1).join('')
	          : string.slice(1);
	
	        return chr[methodName]() + trailing;
	      };
	    }
	
	    /**
	     * Creates a function like `_.camelCase`.
	     *
	     * @private
	     * @param {Function} callback The function to combine each word.
	     * @returns {Function} Returns the new compounder function.
	     */
	    function createCompounder(callback) {
	      return function(string) {
	        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
	      };
	    }
	
	    /**
	     * Creates a function that produces an instance of `Ctor` regardless of
	     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
	     *
	     * @private
	     * @param {Function} Ctor The constructor to wrap.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createCtor(Ctor) {
	      return function() {
	        // Use a `switch` statement to work with class constructors. See
	        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
	        // for more details.
	        var args = arguments;
	        switch (args.length) {
	          case 0: return new Ctor;
	          case 1: return new Ctor(args[0]);
	          case 2: return new Ctor(args[0], args[1]);
	          case 3: return new Ctor(args[0], args[1], args[2]);
	          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
	          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
	          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
	          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
	        }
	        var thisBinding = baseCreate(Ctor.prototype),
	            result = Ctor.apply(thisBinding, args);
	
	        // Mimic the constructor's `return` behavior.
	        // See https://es5.github.io/#x13.2.2 for more details.
	        return isObject(result) ? result : thisBinding;
	      };
	    }
	
	    /**
	     * Creates a function that wraps `func` to enable currying.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {number} arity The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createCurry(func, bitmask, arity) {
	      var Ctor = createCtor(func);
	
	      function wrapper() {
	        var length = arguments.length,
	            args = Array(length),
	            index = length,
	            placeholder = getHolder(wrapper);
	
	        while (index--) {
	          args[index] = arguments[index];
	        }
	        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
	          ? []
	          : replaceHolders(args, placeholder);
	
	        length -= holders.length;
	        if (length < arity) {
	          return createRecurry(
	            func, bitmask, createHybrid, wrapper.placeholder, undefined,
	            args, holders, undefined, undefined, arity - length);
	        }
	        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
	        return apply(fn, this, args);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a `_.find` or `_.findLast` function.
	     *
	     * @private
	     * @param {Function} findIndexFunc The function to find the collection index.
	     * @returns {Function} Returns the new find function.
	     */
	    function createFind(findIndexFunc) {
	      return function(collection, predicate, fromIndex) {
	        var iterable = Object(collection);
	        if (!isArrayLike(collection)) {
	          var iteratee = getIteratee(predicate, 3);
	          collection = keys(collection);
	          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
	        }
	        var index = findIndexFunc(collection, predicate, fromIndex);
	        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
	      };
	    }
	
	    /**
	     * Creates a `_.flow` or `_.flowRight` function.
	     *
	     * @private
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new flow function.
	     */
	    function createFlow(fromRight) {
	      return flatRest(function(funcs) {
	        var length = funcs.length,
	            index = length,
	            prereq = LodashWrapper.prototype.thru;
	
	        if (fromRight) {
	          funcs.reverse();
	        }
	        while (index--) {
	          var func = funcs[index];
	          if (typeof func != 'function') {
	            throw new TypeError(FUNC_ERROR_TEXT);
	          }
	          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
	            var wrapper = new LodashWrapper([], true);
	          }
	        }
	        index = wrapper ? index : length;
	        while (++index < length) {
	          func = funcs[index];
	
	          var funcName = getFuncName(func),
	              data = funcName == 'wrapper' ? getData(func) : undefined;
	
	          if (data && isLaziable(data[0]) &&
	                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
	                !data[4].length && data[9] == 1
	              ) {
	            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
	          } else {
	            wrapper = (func.length == 1 && isLaziable(func))
	              ? wrapper[funcName]()
	              : wrapper.thru(func);
	          }
	        }
	        return function() {
	          var args = arguments,
	              value = args[0];
	
	          if (wrapper && args.length == 1 && isArray(value)) {
	            return wrapper.plant(value).value();
	          }
	          var index = 0,
	              result = length ? funcs[index].apply(this, args) : value;
	
	          while (++index < length) {
	            result = funcs[index].call(this, result);
	          }
	          return result;
	        };
	      });
	    }
	
	    /**
	     * Creates a function that wraps `func` to invoke it with optional `this`
	     * binding of `thisArg`, partial application, and currying.
	     *
	     * @private
	     * @param {Function|string} func The function or method name to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @param {Array} [partials] The arguments to prepend to those provided to
	     *  the new function.
	     * @param {Array} [holders] The `partials` placeholder indexes.
	     * @param {Array} [partialsRight] The arguments to append to those provided
	     *  to the new function.
	     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
	     * @param {Array} [argPos] The argument positions of the new function.
	     * @param {number} [ary] The arity cap of `func`.
	     * @param {number} [arity] The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
	      var isAry = bitmask & WRAP_ARY_FLAG,
	          isBind = bitmask & WRAP_BIND_FLAG,
	          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
	          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
	          isFlip = bitmask & WRAP_FLIP_FLAG,
	          Ctor = isBindKey ? undefined : createCtor(func);
	
	      function wrapper() {
	        var length = arguments.length,
	            args = Array(length),
	            index = length;
	
	        while (index--) {
	          args[index] = arguments[index];
	        }
	        if (isCurried) {
	          var placeholder = getHolder(wrapper),
	              holdersCount = countHolders(args, placeholder);
	        }
	        if (partials) {
	          args = composeArgs(args, partials, holders, isCurried);
	        }
	        if (partialsRight) {
	          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
	        }
	        length -= holdersCount;
	        if (isCurried && length < arity) {
	          var newHolders = replaceHolders(args, placeholder);
	          return createRecurry(
	            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
	            args, newHolders, argPos, ary, arity - length
	          );
	        }
	        var thisBinding = isBind ? thisArg : this,
	            fn = isBindKey ? thisBinding[func] : func;
	
	        length = args.length;
	        if (argPos) {
	          args = reorder(args, argPos);
	        } else if (isFlip && length > 1) {
	          args.reverse();
	        }
	        if (isAry && ary < length) {
	          args.length = ary;
	        }
	        if (this && this !== root && this instanceof wrapper) {
	          fn = Ctor || createCtor(fn);
	        }
	        return fn.apply(thisBinding, args);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a function like `_.invertBy`.
	     *
	     * @private
	     * @param {Function} setter The function to set accumulator values.
	     * @param {Function} toIteratee The function to resolve iteratees.
	     * @returns {Function} Returns the new inverter function.
	     */
	    function createInverter(setter, toIteratee) {
	      return function(object, iteratee) {
	        return baseInverter(object, setter, toIteratee(iteratee), {});
	      };
	    }
	
	    /**
	     * Creates a function that performs a mathematical operation on two values.
	     *
	     * @private
	     * @param {Function} operator The function to perform the operation.
	     * @param {number} [defaultValue] The value used for `undefined` arguments.
	     * @returns {Function} Returns the new mathematical operation function.
	     */
	    function createMathOperation(operator, defaultValue) {
	      return function(value, other) {
	        var result;
	        if (value === undefined && other === undefined) {
	          return defaultValue;
	        }
	        if (value !== undefined) {
	          result = value;
	        }
	        if (other !== undefined) {
	          if (result === undefined) {
	            return other;
	          }
	          if (typeof value == 'string' || typeof other == 'string') {
	            value = baseToString(value);
	            other = baseToString(other);
	          } else {
	            value = baseToNumber(value);
	            other = baseToNumber(other);
	          }
	          result = operator(value, other);
	        }
	        return result;
	      };
	    }
	
	    /**
	     * Creates a function like `_.over`.
	     *
	     * @private
	     * @param {Function} arrayFunc The function to iterate over iteratees.
	     * @returns {Function} Returns the new over function.
	     */
	    function createOver(arrayFunc) {
	      return flatRest(function(iteratees) {
	        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
	        return baseRest(function(args) {
	          var thisArg = this;
	          return arrayFunc(iteratees, function(iteratee) {
	            return apply(iteratee, thisArg, args);
	          });
	        });
	      });
	    }
	
	    /**
	     * Creates the padding for `string` based on `length`. The `chars` string
	     * is truncated if the number of characters exceeds `length`.
	     *
	     * @private
	     * @param {number} length The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padding for `string`.
	     */
	    function createPadding(length, chars) {
	      chars = chars === undefined ? ' ' : baseToString(chars);
	
	      var charsLength = chars.length;
	      if (charsLength < 2) {
	        return charsLength ? baseRepeat(chars, length) : chars;
	      }
	      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
	      return hasUnicode(chars)
	        ? castSlice(stringToArray(result), 0, length).join('')
	        : result.slice(0, length);
	    }
	
	    /**
	     * Creates a function that wraps `func` to invoke it with the `this` binding
	     * of `thisArg` and `partials` prepended to the arguments it receives.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {*} thisArg The `this` binding of `func`.
	     * @param {Array} partials The arguments to prepend to those provided to
	     *  the new function.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createPartial(func, bitmask, thisArg, partials) {
	      var isBind = bitmask & WRAP_BIND_FLAG,
	          Ctor = createCtor(func);
	
	      function wrapper() {
	        var argsIndex = -1,
	            argsLength = arguments.length,
	            leftIndex = -1,
	            leftLength = partials.length,
	            args = Array(leftLength + argsLength),
	            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
	
	        while (++leftIndex < leftLength) {
	          args[leftIndex] = partials[leftIndex];
	        }
	        while (argsLength--) {
	          args[leftIndex++] = arguments[++argsIndex];
	        }
	        return apply(fn, isBind ? thisArg : this, args);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a `_.range` or `_.rangeRight` function.
	     *
	     * @private
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new range function.
	     */
	    function createRange(fromRight) {
	      return function(start, end, step) {
	        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
	          end = step = undefined;
	        }
	        // Ensure the sign of `-0` is preserved.
	        start = toFinite(start);
	        if (end === undefined) {
	          end = start;
	          start = 0;
	        } else {
	          end = toFinite(end);
	        }
	        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
	        return baseRange(start, end, step, fromRight);
	      };
	    }
	
	    /**
	     * Creates a function that performs a relational operation on two values.
	     *
	     * @private
	     * @param {Function} operator The function to perform the operation.
	     * @returns {Function} Returns the new relational operation function.
	     */
	    function createRelationalOperation(operator) {
	      return function(value, other) {
	        if (!(typeof value == 'string' && typeof other == 'string')) {
	          value = toNumber(value);
	          other = toNumber(other);
	        }
	        return operator(value, other);
	      };
	    }
	
	    /**
	     * Creates a function that wraps `func` to continue currying.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {Function} wrapFunc The function to create the `func` wrapper.
	     * @param {*} placeholder The placeholder value.
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @param {Array} [partials] The arguments to prepend to those provided to
	     *  the new function.
	     * @param {Array} [holders] The `partials` placeholder indexes.
	     * @param {Array} [argPos] The argument positions of the new function.
	     * @param {number} [ary] The arity cap of `func`.
	     * @param {number} [arity] The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
	      var isCurry = bitmask & WRAP_CURRY_FLAG,
	          newHolders = isCurry ? holders : undefined,
	          newHoldersRight = isCurry ? undefined : holders,
	          newPartials = isCurry ? partials : undefined,
	          newPartialsRight = isCurry ? undefined : partials;
	
	      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
	      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
	
	      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
	        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
	      }
	      var newData = [
	        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
	        newHoldersRight, argPos, ary, arity
	      ];
	
	      var result = wrapFunc.apply(undefined, newData);
	      if (isLaziable(func)) {
	        setData(result, newData);
	      }
	      result.placeholder = placeholder;
	      return setWrapToString(result, func, bitmask);
	    }
	
	    /**
	     * Creates a function like `_.round`.
	     *
	     * @private
	     * @param {string} methodName The name of the `Math` method to use when rounding.
	     * @returns {Function} Returns the new round function.
	     */
	    function createRound(methodName) {
	      var func = Math[methodName];
	      return function(number, precision) {
	        number = toNumber(number);
	        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
	        if (precision) {
	          // Shift with exponential notation to avoid floating-point issues.
	          // See [MDN](https://mdn.io/round#Examples) for more details.
	          var pair = (toString(number) + 'e').split('e'),
	              value = func(pair[0] + 'e' + (+pair[1] + precision));
	
	          pair = (toString(value) + 'e').split('e');
	          return +(pair[0] + 'e' + (+pair[1] - precision));
	        }
	        return func(number);
	      };
	    }
	
	    /**
	     * Creates a set object of `values`.
	     *
	     * @private
	     * @param {Array} values The values to add to the set.
	     * @returns {Object} Returns the new set.
	     */
	    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
	      return new Set(values);
	    };
	
	    /**
	     * Creates a `_.toPairs` or `_.toPairsIn` function.
	     *
	     * @private
	     * @param {Function} keysFunc The function to get the keys of a given object.
	     * @returns {Function} Returns the new pairs function.
	     */
	    function createToPairs(keysFunc) {
	      return function(object) {
	        var tag = getTag(object);
	        if (tag == mapTag) {
	          return mapToArray(object);
	        }
	        if (tag == setTag) {
	          return setToPairs(object);
	        }
	        return baseToPairs(object, keysFunc(object));
	      };
	    }
	
	    /**
	     * Creates a function that either curries or invokes `func` with optional
	     * `this` binding and partially applied arguments.
	     *
	     * @private
	     * @param {Function|string} func The function or method name to wrap.
	     * @param {number} bitmask The bitmask flags.
	     *    1 - `_.bind`
	     *    2 - `_.bindKey`
	     *    4 - `_.curry` or `_.curryRight` of a bound function
	     *    8 - `_.curry`
	     *   16 - `_.curryRight`
	     *   32 - `_.partial`
	     *   64 - `_.partialRight`
	     *  128 - `_.rearg`
	     *  256 - `_.ary`
	     *  512 - `_.flip`
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @param {Array} [partials] The arguments to be partially applied.
	     * @param {Array} [holders] The `partials` placeholder indexes.
	     * @param {Array} [argPos] The argument positions of the new function.
	     * @param {number} [ary] The arity cap of `func`.
	     * @param {number} [arity] The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
	      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
	      if (!isBindKey && typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      var length = partials ? partials.length : 0;
	      if (!length) {
	        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
	        partials = holders = undefined;
	      }
	      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
	      arity = arity === undefined ? arity : toInteger(arity);
	      length -= holders ? holders.length : 0;
	
	      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
	        var partialsRight = partials,
	            holdersRight = holders;
	
	        partials = holders = undefined;
	      }
	      var data = isBindKey ? undefined : getData(func);
	
	      var newData = [
	        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
	        argPos, ary, arity
	      ];
	
	      if (data) {
	        mergeData(newData, data);
	      }
	      func = newData[0];
	      bitmask = newData[1];
	      thisArg = newData[2];
	      partials = newData[3];
	      holders = newData[4];
	      arity = newData[9] = newData[9] === undefined
	        ? (isBindKey ? 0 : func.length)
	        : nativeMax(newData[9] - length, 0);
	
	      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
	        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
	      }
	      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
	        var result = createBind(func, bitmask, thisArg);
	      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
	        result = createCurry(func, bitmask, arity);
	      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
	        result = createPartial(func, bitmask, thisArg, partials);
	      } else {
	        result = createHybrid.apply(undefined, newData);
	      }
	      var setter = data ? baseSetData : setData;
	      return setWrapToString(setter(result, newData), func, bitmask);
	    }
	
	    /**
	     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
	     * of source objects to the destination object for all destination properties
	     * that resolve to `undefined`.
	     *
	     * @private
	     * @param {*} objValue The destination value.
	     * @param {*} srcValue The source value.
	     * @param {string} key The key of the property to assign.
	     * @param {Object} object The parent object of `objValue`.
	     * @returns {*} Returns the value to assign.
	     */
	    function customDefaultsAssignIn(objValue, srcValue, key, object) {
	      if (objValue === undefined ||
	          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
	        return srcValue;
	      }
	      return objValue;
	    }
	
	    /**
	     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
	     * objects into destination objects that are passed thru.
	     *
	     * @private
	     * @param {*} objValue The destination value.
	     * @param {*} srcValue The source value.
	     * @param {string} key The key of the property to merge.
	     * @param {Object} object The parent object of `objValue`.
	     * @param {Object} source The parent object of `srcValue`.
	     * @param {Object} [stack] Tracks traversed source values and their merged
	     *  counterparts.
	     * @returns {*} Returns the value to assign.
	     */
	    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
	      if (isObject(objValue) && isObject(srcValue)) {
	        // Recursively merge objects and arrays (susceptible to call stack limits).
	        stack.set(srcValue, objValue);
	        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
	        stack['delete'](srcValue);
	      }
	      return objValue;
	    }
	
	    /**
	     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
	     * objects.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @param {string} key The key of the property to inspect.
	     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
	     */
	    function customOmitClone(value) {
	      return isPlainObject(value) ? undefined : value;
	    }
	
	    /**
	     * A specialized version of `baseIsEqualDeep` for arrays with support for
	     * partial deep comparisons.
	     *
	     * @private
	     * @param {Array} array The array to compare.
	     * @param {Array} other The other array to compare.
	     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	     * @param {Function} customizer The function to customize comparisons.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Object} stack Tracks traversed `array` and `other` objects.
	     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
	     */
	    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
	      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
	          arrLength = array.length,
	          othLength = other.length;
	
	      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
	        return false;
	      }
	      // Assume cyclic values are equal.
	      var stacked = stack.get(array);
	      if (stacked && stack.get(other)) {
	        return stacked == other;
	      }
	      var index = -1,
	          result = true,
	          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
	
	      stack.set(array, other);
	      stack.set(other, array);
	
	      // Ignore non-index properties.
	      while (++index < arrLength) {
	        var arrValue = array[index],
	            othValue = other[index];
	
	        if (customizer) {
	          var compared = isPartial
	            ? customizer(othValue, arrValue, index, other, array, stack)
	            : customizer(arrValue, othValue, index, array, other, stack);
	        }
	        if (compared !== undefined) {
	          if (compared) {
	            continue;
	          }
	          result = false;
	          break;
	        }
	        // Recursively compare arrays (susceptible to call stack limits).
	        if (seen) {
	          if (!arraySome(other, function(othValue, othIndex) {
	                if (!cacheHas(seen, othIndex) &&
	                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
	                  return seen.push(othIndex);
	                }
	              })) {
	            result = false;
	            break;
	          }
	        } else if (!(
	              arrValue === othValue ||
	                equalFunc(arrValue, othValue, bitmask, customizer, stack)
	            )) {
	          result = false;
	          break;
	        }
	      }
	      stack['delete'](array);
	      stack['delete'](other);
	      return result;
	    }
	
	    /**
	     * A specialized version of `baseIsEqualDeep` for comparing objects of
	     * the same `toStringTag`.
	     *
	     * **Note:** This function only supports comparing values with tags of
	     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {string} tag The `toStringTag` of the objects to compare.
	     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	     * @param {Function} customizer The function to customize comparisons.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Object} stack Tracks traversed `object` and `other` objects.
	     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	     */
	    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
	      switch (tag) {
	        case dataViewTag:
	          if ((object.byteLength != other.byteLength) ||
	              (object.byteOffset != other.byteOffset)) {
	            return false;
	          }
	          object = object.buffer;
	          other = other.buffer;
	
	        case arrayBufferTag:
	          if ((object.byteLength != other.byteLength) ||
	              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
	            return false;
	          }
	          return true;
	
	        case boolTag:
	        case dateTag:
	        case numberTag:
	          // Coerce booleans to `1` or `0` and dates to milliseconds.
	          // Invalid dates are coerced to `NaN`.
	          return eq(+object, +other);
	
	        case errorTag:
	          return object.name == other.name && object.message == other.message;
	
	        case regexpTag:
	        case stringTag:
	          // Coerce regexes to strings and treat strings, primitives and objects,
	          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
	          // for more details.
	          return object == (other + '');
	
	        case mapTag:
	          var convert = mapToArray;
	
	        case setTag:
	          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
	          convert || (convert = setToArray);
	
	          if (object.size != other.size && !isPartial) {
	            return false;
	          }
	          // Assume cyclic values are equal.
	          var stacked = stack.get(object);
	          if (stacked) {
	            return stacked == other;
	          }
	          bitmask |= COMPARE_UNORDERED_FLAG;
	
	          // Recursively compare objects (susceptible to call stack limits).
	          stack.set(object, other);
	          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
	          stack['delete'](object);
	          return result;
	
	        case symbolTag:
	          if (symbolValueOf) {
	            return symbolValueOf.call(object) == symbolValueOf.call(other);
	          }
	      }
	      return false;
	    }
	
	    /**
	     * A specialized version of `baseIsEqualDeep` for objects with support for
	     * partial deep comparisons.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
	     * @param {Function} customizer The function to customize comparisons.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Object} stack Tracks traversed `object` and `other` objects.
	     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	     */
	    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
	      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
	          objProps = getAllKeys(object),
	          objLength = objProps.length,
	          othProps = getAllKeys(other),
	          othLength = othProps.length;
	
	      if (objLength != othLength && !isPartial) {
	        return false;
	      }
	      var index = objLength;
	      while (index--) {
	        var key = objProps[index];
	        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
	          return false;
	        }
	      }
	      // Assume cyclic values are equal.
	      var stacked = stack.get(object);
	      if (stacked && stack.get(other)) {
	        return stacked == other;
	      }
	      var result = true;
	      stack.set(object, other);
	      stack.set(other, object);
	
	      var skipCtor = isPartial;
	      while (++index < objLength) {
	        key = objProps[index];
	        var objValue = object[key],
	            othValue = other[key];
	
	        if (customizer) {
	          var compared = isPartial
	            ? customizer(othValue, objValue, key, other, object, stack)
	            : customizer(objValue, othValue, key, object, other, stack);
	        }
	        // Recursively compare objects (susceptible to call stack limits).
	        if (!(compared === undefined
	              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
	              : compared
	            )) {
	          result = false;
	          break;
	        }
	        skipCtor || (skipCtor = key == 'constructor');
	      }
	      if (result && !skipCtor) {
	        var objCtor = object.constructor,
	            othCtor = other.constructor;
	
	        // Non `Object` object instances with different constructors are not equal.
	        if (objCtor != othCtor &&
	            ('constructor' in object && 'constructor' in other) &&
	            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
	              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
	          result = false;
	        }
	      }
	      stack['delete'](object);
	      stack['delete'](other);
	      return result;
	    }
	
	    /**
	     * A specialized version of `baseRest` which flattens the rest array.
	     *
	     * @private
	     * @param {Function} func The function to apply a rest parameter to.
	     * @returns {Function} Returns the new function.
	     */
	    function flatRest(func) {
	      return setToString(overRest(func, undefined, flatten), func + '');
	    }
	
	    /**
	     * Creates an array of own enumerable property names and symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names and symbols.
	     */
	    function getAllKeys(object) {
	      return baseGetAllKeys(object, keys, getSymbols);
	    }
	
	    /**
	     * Creates an array of own and inherited enumerable property names and
	     * symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names and symbols.
	     */
	    function getAllKeysIn(object) {
	      return baseGetAllKeys(object, keysIn, getSymbolsIn);
	    }
	
	    /**
	     * Gets metadata for `func`.
	     *
	     * @private
	     * @param {Function} func The function to query.
	     * @returns {*} Returns the metadata for `func`.
	     */
	    var getData = !metaMap ? noop : function(func) {
	      return metaMap.get(func);
	    };
	
	    /**
	     * Gets the name of `func`.
	     *
	     * @private
	     * @param {Function} func The function to query.
	     * @returns {string} Returns the function name.
	     */
	    function getFuncName(func) {
	      var result = (func.name + ''),
	          array = realNames[result],
	          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
	
	      while (length--) {
	        var data = array[length],
	            otherFunc = data.func;
	        if (otherFunc == null || otherFunc == func) {
	          return data.name;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Gets the argument placeholder value for `func`.
	     *
	     * @private
	     * @param {Function} func The function to inspect.
	     * @returns {*} Returns the placeholder value.
	     */
	    function getHolder(func) {
	      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
	      return object.placeholder;
	    }
	
	    /**
	     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
	     * this function returns the custom method, otherwise it returns `baseIteratee`.
	     * If arguments are provided, the chosen function is invoked with them and
	     * its result is returned.
	     *
	     * @private
	     * @param {*} [value] The value to convert to an iteratee.
	     * @param {number} [arity] The arity of the created iteratee.
	     * @returns {Function} Returns the chosen function or its result.
	     */
	    function getIteratee() {
	      var result = lodash.iteratee || iteratee;
	      result = result === iteratee ? baseIteratee : result;
	      return arguments.length ? result(arguments[0], arguments[1]) : result;
	    }
	
	    /**
	     * Gets the data for `map`.
	     *
	     * @private
	     * @param {Object} map The map to query.
	     * @param {string} key The reference key.
	     * @returns {*} Returns the map data.
	     */
	    function getMapData(map, key) {
	      var data = map.__data__;
	      return isKeyable(key)
	        ? data[typeof key == 'string' ? 'string' : 'hash']
	        : data.map;
	    }
	
	    /**
	     * Gets the property names, values, and compare flags of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the match data of `object`.
	     */
	    function getMatchData(object) {
	      var result = keys(object),
	          length = result.length;
	
	      while (length--) {
	        var key = result[length],
	            value = object[key];
	
	        result[length] = [key, value, isStrictComparable(value)];
	      }
	      return result;
	    }
	
	    /**
	     * Gets the native function at `key` of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {string} key The key of the method to get.
	     * @returns {*} Returns the function if it's native, else `undefined`.
	     */
	    function getNative(object, key) {
	      var value = getValue(object, key);
	      return baseIsNative(value) ? value : undefined;
	    }
	
	    /**
	     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
	     *
	     * @private
	     * @param {*} value The value to query.
	     * @returns {string} Returns the raw `toStringTag`.
	     */
	    function getRawTag(value) {
	      var isOwn = hasOwnProperty.call(value, symToStringTag),
	          tag = value[symToStringTag];
	
	      try {
	        value[symToStringTag] = undefined;
	        var unmasked = true;
	      } catch (e) {}
	
	      var result = nativeObjectToString.call(value);
	      if (unmasked) {
	        if (isOwn) {
	          value[symToStringTag] = tag;
	        } else {
	          delete value[symToStringTag];
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Creates an array of the own enumerable symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of symbols.
	     */
	    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
	      if (object == null) {
	        return [];
	      }
	      object = Object(object);
	      return arrayFilter(nativeGetSymbols(object), function(symbol) {
	        return propertyIsEnumerable.call(object, symbol);
	      });
	    };
	
	    /**
	     * Creates an array of the own and inherited enumerable symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of symbols.
	     */
	    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
	      var result = [];
	      while (object) {
	        arrayPush(result, getSymbols(object));
	        object = getPrototype(object);
	      }
	      return result;
	    };
	
	    /**
	     * Gets the `toStringTag` of `value`.
	     *
	     * @private
	     * @param {*} value The value to query.
	     * @returns {string} Returns the `toStringTag`.
	     */
	    var getTag = baseGetTag;
	
	    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
	    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
	        (Map && getTag(new Map) != mapTag) ||
	        (Promise && getTag(Promise.resolve()) != promiseTag) ||
	        (Set && getTag(new Set) != setTag) ||
	        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
	      getTag = function(value) {
	        var result = baseGetTag(value),
	            Ctor = result == objectTag ? value.constructor : undefined,
	            ctorString = Ctor ? toSource(Ctor) : '';
	
	        if (ctorString) {
	          switch (ctorString) {
	            case dataViewCtorString: return dataViewTag;
	            case mapCtorString: return mapTag;
	            case promiseCtorString: return promiseTag;
	            case setCtorString: return setTag;
	            case weakMapCtorString: return weakMapTag;
	          }
	        }
	        return result;
	      };
	    }
	
	    /**
	     * Gets the view, applying any `transforms` to the `start` and `end` positions.
	     *
	     * @private
	     * @param {number} start The start of the view.
	     * @param {number} end The end of the view.
	     * @param {Array} transforms The transformations to apply to the view.
	     * @returns {Object} Returns an object containing the `start` and `end`
	     *  positions of the view.
	     */
	    function getView(start, end, transforms) {
	      var index = -1,
	          length = transforms.length;
	
	      while (++index < length) {
	        var data = transforms[index],
	            size = data.size;
	
	        switch (data.type) {
	          case 'drop':      start += size; break;
	          case 'dropRight': end -= size; break;
	          case 'take':      end = nativeMin(end, start + size); break;
	          case 'takeRight': start = nativeMax(start, end - size); break;
	        }
	      }
	      return { 'start': start, 'end': end };
	    }
	
	    /**
	     * Extracts wrapper details from the `source` body comment.
	     *
	     * @private
	     * @param {string} source The source to inspect.
	     * @returns {Array} Returns the wrapper details.
	     */
	    function getWrapDetails(source) {
	      var match = source.match(reWrapDetails);
	      return match ? match[1].split(reSplitDetails) : [];
	    }
	
	    /**
	     * Checks if `path` exists on `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path to check.
	     * @param {Function} hasFunc The function to check properties.
	     * @returns {boolean} Returns `true` if `path` exists, else `false`.
	     */
	    function hasPath(object, path, hasFunc) {
	      path = castPath(path, object);
	
	      var index = -1,
	          length = path.length,
	          result = false;
	
	      while (++index < length) {
	        var key = toKey(path[index]);
	        if (!(result = object != null && hasFunc(object, key))) {
	          break;
	        }
	        object = object[key];
	      }
	      if (result || ++index != length) {
	        return result;
	      }
	      length = object == null ? 0 : object.length;
	      return !!length && isLength(length) && isIndex(key, length) &&
	        (isArray(object) || isArguments(object));
	    }
	
	    /**
	     * Initializes an array clone.
	     *
	     * @private
	     * @param {Array} array The array to clone.
	     * @returns {Array} Returns the initialized clone.
	     */
	    function initCloneArray(array) {
	      var length = array.length,
	          result = array.constructor(length);
	
	      // Add properties assigned by `RegExp#exec`.
	      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
	        result.index = array.index;
	        result.input = array.input;
	      }
	      return result;
	    }
	
	    /**
	     * Initializes an object clone.
	     *
	     * @private
	     * @param {Object} object The object to clone.
	     * @returns {Object} Returns the initialized clone.
	     */
	    function initCloneObject(object) {
	      return (typeof object.constructor == 'function' && !isPrototype(object))
	        ? baseCreate(getPrototype(object))
	        : {};
	    }
	
	    /**
	     * Initializes an object clone based on its `toStringTag`.
	     *
	     * **Note:** This function only supports cloning values with tags of
	     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
	     *
	     * @private
	     * @param {Object} object The object to clone.
	     * @param {string} tag The `toStringTag` of the object to clone.
	     * @param {Function} cloneFunc The function to clone values.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the initialized clone.
	     */
	    function initCloneByTag(object, tag, cloneFunc, isDeep) {
	      var Ctor = object.constructor;
	      switch (tag) {
	        case arrayBufferTag:
	          return cloneArrayBuffer(object);
	
	        case boolTag:
	        case dateTag:
	          return new Ctor(+object);
	
	        case dataViewTag:
	          return cloneDataView(object, isDeep);
	
	        case float32Tag: case float64Tag:
	        case int8Tag: case int16Tag: case int32Tag:
	        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
	          return cloneTypedArray(object, isDeep);
	
	        case mapTag:
	          return cloneMap(object, isDeep, cloneFunc);
	
	        case numberTag:
	        case stringTag:
	          return new Ctor(object);
	
	        case regexpTag:
	          return cloneRegExp(object);
	
	        case setTag:
	          return cloneSet(object, isDeep, cloneFunc);
	
	        case symbolTag:
	          return cloneSymbol(object);
	      }
	    }
	
	    /**
	     * Inserts wrapper `details` in a comment at the top of the `source` body.
	     *
	     * @private
	     * @param {string} source The source to modify.
	     * @returns {Array} details The details to insert.
	     * @returns {string} Returns the modified source.
	     */
	    function insertWrapDetails(source, details) {
	      var length = details.length;
	      if (!length) {
	        return source;
	      }
	      var lastIndex = length - 1;
	      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
	      details = details.join(length > 2 ? ', ' : ' ');
	      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
	    }
	
	    /**
	     * Checks if `value` is a flattenable `arguments` object or array.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
	     */
	    function isFlattenable(value) {
	      return isArray(value) || isArguments(value) ||
	        !!(spreadableSymbol && value && value[spreadableSymbol]);
	    }
	
	    /**
	     * Checks if `value` is a valid array-like index.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
	     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
	     */
	    function isIndex(value, length) {
	      length = length == null ? MAX_SAFE_INTEGER : length;
	      return !!length &&
	        (typeof value == 'number' || reIsUint.test(value)) &&
	        (value > -1 && value % 1 == 0 && value < length);
	    }
	
	    /**
	     * Checks if the given arguments are from an iteratee call.
	     *
	     * @private
	     * @param {*} value The potential iteratee value argument.
	     * @param {*} index The potential iteratee index or key argument.
	     * @param {*} object The potential iteratee object argument.
	     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
	     *  else `false`.
	     */
	    function isIterateeCall(value, index, object) {
	      if (!isObject(object)) {
	        return false;
	      }
	      var type = typeof index;
	      if (type == 'number'
	            ? (isArrayLike(object) && isIndex(index, object.length))
	            : (type == 'string' && index in object)
	          ) {
	        return eq(object[index], value);
	      }
	      return false;
	    }
	
	    /**
	     * Checks if `value` is a property name and not a property path.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @param {Object} [object] The object to query keys on.
	     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
	     */
	    function isKey(value, object) {
	      if (isArray(value)) {
	        return false;
	      }
	      var type = typeof value;
	      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
	          value == null || isSymbol(value)) {
	        return true;
	      }
	      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
	        (object != null && value in Object(object));
	    }
	
	    /**
	     * Checks if `value` is suitable for use as unique object key.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
	     */
	    function isKeyable(value) {
	      var type = typeof value;
	      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
	        ? (value !== '__proto__')
	        : (value === null);
	    }
	
	    /**
	     * Checks if `func` has a lazy counterpart.
	     *
	     * @private
	     * @param {Function} func The function to check.
	     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
	     *  else `false`.
	     */
	    function isLaziable(func) {
	      var funcName = getFuncName(func),
	          other = lodash[funcName];
	
	      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
	        return false;
	      }
	      if (func === other) {
	        return true;
	      }
	      var data = getData(other);
	      return !!data && func === data[0];
	    }
	
	    /**
	     * Checks if `func` has its source masked.
	     *
	     * @private
	     * @param {Function} func The function to check.
	     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
	     */
	    function isMasked(func) {
	      return !!maskSrcKey && (maskSrcKey in func);
	    }
	
	    /**
	     * Checks if `func` is capable of being masked.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
	     */
	    var isMaskable = coreJsData ? isFunction : stubFalse;
	
	    /**
	     * Checks if `value` is likely a prototype object.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
	     */
	    function isPrototype(value) {
	      var Ctor = value && value.constructor,
	          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
	
	      return value === proto;
	    }
	
	    /**
	     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` if suitable for strict
	     *  equality comparisons, else `false`.
	     */
	    function isStrictComparable(value) {
	      return value === value && !isObject(value);
	    }
	
	    /**
	     * A specialized version of `matchesProperty` for source values suitable
	     * for strict equality comparisons, i.e. `===`.
	     *
	     * @private
	     * @param {string} key The key of the property to get.
	     * @param {*} srcValue The value to match.
	     * @returns {Function} Returns the new spec function.
	     */
	    function matchesStrictComparable(key, srcValue) {
	      return function(object) {
	        if (object == null) {
	          return false;
	        }
	        return object[key] === srcValue &&
	          (srcValue !== undefined || (key in Object(object)));
	      };
	    }
	
	    /**
	     * A specialized version of `_.memoize` which clears the memoized function's
	     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
	     *
	     * @private
	     * @param {Function} func The function to have its output memoized.
	     * @returns {Function} Returns the new memoized function.
	     */
	    function memoizeCapped(func) {
	      var result = memoize(func, function(key) {
	        if (cache.size === MAX_MEMOIZE_SIZE) {
	          cache.clear();
	        }
	        return key;
	      });
	
	      var cache = result.cache;
	      return result;
	    }
	
	    /**
	     * Merges the function metadata of `source` into `data`.
	     *
	     * Merging metadata reduces the number of wrappers used to invoke a function.
	     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
	     * may be applied regardless of execution order. Methods like `_.ary` and
	     * `_.rearg` modify function arguments, making the order in which they are
	     * executed important, preventing the merging of metadata. However, we make
	     * an exception for a safe combined case where curried functions have `_.ary`
	     * and or `_.rearg` applied.
	     *
	     * @private
	     * @param {Array} data The destination metadata.
	     * @param {Array} source The source metadata.
	     * @returns {Array} Returns `data`.
	     */
	    function mergeData(data, source) {
	      var bitmask = data[1],
	          srcBitmask = source[1],
	          newBitmask = bitmask | srcBitmask,
	          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
	
	      var isCombo =
	        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
	        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
	        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
	
	      // Exit early if metadata can't be merged.
	      if (!(isCommon || isCombo)) {
	        return data;
	      }
	      // Use source `thisArg` if available.
	      if (srcBitmask & WRAP_BIND_FLAG) {
	        data[2] = source[2];
	        // Set when currying a bound function.
	        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
	      }
	      // Compose partial arguments.
	      var value = source[3];
	      if (value) {
	        var partials = data[3];
	        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
	        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
	      }
	      // Compose partial right arguments.
	      value = source[5];
	      if (value) {
	        partials = data[5];
	        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
	        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
	      }
	      // Use source `argPos` if available.
	      value = source[7];
	      if (value) {
	        data[7] = value;
	      }
	      // Use source `ary` if it's smaller.
	      if (srcBitmask & WRAP_ARY_FLAG) {
	        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
	      }
	      // Use source `arity` if one is not provided.
	      if (data[9] == null) {
	        data[9] = source[9];
	      }
	      // Use source `func` and merge bitmasks.
	      data[0] = source[0];
	      data[1] = newBitmask;
	
	      return data;
	    }
	
	    /**
	     * This function is like
	     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
	     * except that it includes inherited enumerable properties.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     */
	    function nativeKeysIn(object) {
	      var result = [];
	      if (object != null) {
	        for (var key in Object(object)) {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Converts `value` to a string using `Object.prototype.toString`.
	     *
	     * @private
	     * @param {*} value The value to convert.
	     * @returns {string} Returns the converted string.
	     */
	    function objectToString(value) {
	      return nativeObjectToString.call(value);
	    }
	
	    /**
	     * A specialized version of `baseRest` which transforms the rest array.
	     *
	     * @private
	     * @param {Function} func The function to apply a rest parameter to.
	     * @param {number} [start=func.length-1] The start position of the rest parameter.
	     * @param {Function} transform The rest array transform.
	     * @returns {Function} Returns the new function.
	     */
	    function overRest(func, start, transform) {
	      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
	      return function() {
	        var args = arguments,
	            index = -1,
	            length = nativeMax(args.length - start, 0),
	            array = Array(length);
	
	        while (++index < length) {
	          array[index] = args[start + index];
	        }
	        index = -1;
	        var otherArgs = Array(start + 1);
	        while (++index < start) {
	          otherArgs[index] = args[index];
	        }
	        otherArgs[start] = transform(array);
	        return apply(func, this, otherArgs);
	      };
	    }
	
	    /**
	     * Gets the parent value at `path` of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Array} path The path to get the parent value of.
	     * @returns {*} Returns the parent value.
	     */
	    function parent(object, path) {
	      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
	    }
	
	    /**
	     * Reorder `array` according to the specified indexes where the element at
	     * the first index is assigned as the first element, the element at
	     * the second index is assigned as the second element, and so on.
	     *
	     * @private
	     * @param {Array} array The array to reorder.
	     * @param {Array} indexes The arranged array indexes.
	     * @returns {Array} Returns `array`.
	     */
	    function reorder(array, indexes) {
	      var arrLength = array.length,
	          length = nativeMin(indexes.length, arrLength),
	          oldArray = copyArray(array);
	
	      while (length--) {
	        var index = indexes[length];
	        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
	      }
	      return array;
	    }
	
	    /**
	     * Sets metadata for `func`.
	     *
	     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
	     * period of time, it will trip its breaker and transition to an identity
	     * function to avoid garbage collection pauses in V8. See
	     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
	     * for more details.
	     *
	     * @private
	     * @param {Function} func The function to associate metadata with.
	     * @param {*} data The metadata.
	     * @returns {Function} Returns `func`.
	     */
	    var setData = shortOut(baseSetData);
	
	    /**
	     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
	     *
	     * @private
	     * @param {Function} func The function to delay.
	     * @param {number} wait The number of milliseconds to delay invocation.
	     * @returns {number|Object} Returns the timer id or timeout object.
	     */
	    var setTimeout = ctxSetTimeout || function(func, wait) {
	      return root.setTimeout(func, wait);
	    };
	
	    /**
	     * Sets the `toString` method of `func` to return `string`.
	     *
	     * @private
	     * @param {Function} func The function to modify.
	     * @param {Function} string The `toString` result.
	     * @returns {Function} Returns `func`.
	     */
	    var setToString = shortOut(baseSetToString);
	
	    /**
	     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
	     * with wrapper details in a comment at the top of the source body.
	     *
	     * @private
	     * @param {Function} wrapper The function to modify.
	     * @param {Function} reference The reference function.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @returns {Function} Returns `wrapper`.
	     */
	    function setWrapToString(wrapper, reference, bitmask) {
	      var source = (reference + '');
	      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
	    }
	
	    /**
	     * Creates a function that'll short out and invoke `identity` instead
	     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
	     * milliseconds.
	     *
	     * @private
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new shortable function.
	     */
	    function shortOut(func) {
	      var count = 0,
	          lastCalled = 0;
	
	      return function() {
	        var stamp = nativeNow(),
	            remaining = HOT_SPAN - (stamp - lastCalled);
	
	        lastCalled = stamp;
	        if (remaining > 0) {
	          if (++count >= HOT_COUNT) {
	            return arguments[0];
	          }
	        } else {
	          count = 0;
	        }
	        return func.apply(undefined, arguments);
	      };
	    }
	
	    /**
	     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
	     *
	     * @private
	     * @param {Array} array The array to shuffle.
	     * @param {number} [size=array.length] The size of `array`.
	     * @returns {Array} Returns `array`.
	     */
	    function shuffleSelf(array, size) {
	      var index = -1,
	          length = array.length,
	          lastIndex = length - 1;
	
	      size = size === undefined ? length : size;
	      while (++index < size) {
	        var rand = baseRandom(index, lastIndex),
	            value = array[rand];
	
	        array[rand] = array[index];
	        array[index] = value;
	      }
	      array.length = size;
	      return array;
	    }
	
	    /**
	     * Converts `string` to a property path array.
	     *
	     * @private
	     * @param {string} string The string to convert.
	     * @returns {Array} Returns the property path array.
	     */
	    var stringToPath = memoizeCapped(function(string) {
	      var result = [];
	      if (reLeadingDot.test(string)) {
	        result.push('');
	      }
	      string.replace(rePropName, function(match, number, quote, string) {
	        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
	      });
	      return result;
	    });
	
	    /**
	     * Converts `value` to a string key if it's not a string or symbol.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @returns {string|symbol} Returns the key.
	     */
	    function toKey(value) {
	      if (typeof value == 'string' || isSymbol(value)) {
	        return value;
	      }
	      var result = (value + '');
	      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
	    }
	
	    /**
	     * Converts `func` to its source code.
	     *
	     * @private
	     * @param {Function} func The function to convert.
	     * @returns {string} Returns the source code.
	     */
	    function toSource(func) {
	      if (func != null) {
	        try {
	          return funcToString.call(func);
	        } catch (e) {}
	        try {
	          return (func + '');
	        } catch (e) {}
	      }
	      return '';
	    }
	
	    /**
	     * Updates wrapper `details` based on `bitmask` flags.
	     *
	     * @private
	     * @returns {Array} details The details to modify.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @returns {Array} Returns `details`.
	     */
	    function updateWrapDetails(details, bitmask) {
	      arrayEach(wrapFlags, function(pair) {
	        var value = '_.' + pair[0];
	        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
	          details.push(value);
	        }
	      });
	      return details.sort();
	    }
	
	    /**
	     * Creates a clone of `wrapper`.
	     *
	     * @private
	     * @param {Object} wrapper The wrapper to clone.
	     * @returns {Object} Returns the cloned wrapper.
	     */
	    function wrapperClone(wrapper) {
	      if (wrapper instanceof LazyWrapper) {
	        return wrapper.clone();
	      }
	      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
	      result.__actions__ = copyArray(wrapper.__actions__);
	      result.__index__  = wrapper.__index__;
	      result.__values__ = wrapper.__values__;
	      return result;
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an array of elements split into groups the length of `size`.
	     * If `array` can't be split evenly, the final chunk will be the remaining
	     * elements.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to process.
	     * @param {number} [size=1] The length of each chunk
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the new array of chunks.
	     * @example
	     *
	     * _.chunk(['a', 'b', 'c', 'd'], 2);
	     * // => [['a', 'b'], ['c', 'd']]
	     *
	     * _.chunk(['a', 'b', 'c', 'd'], 3);
	     * // => [['a', 'b', 'c'], ['d']]
	     */
	    function chunk(array, size, guard) {
	      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
	        size = 1;
	      } else {
	        size = nativeMax(toInteger(size), 0);
	      }
	      var length = array == null ? 0 : array.length;
	      if (!length || size < 1) {
	        return [];
	      }
	      var index = 0,
	          resIndex = 0,
	          result = Array(nativeCeil(length / size));
	
	      while (index < length) {
	        result[resIndex++] = baseSlice(array, index, (index += size));
	      }
	      return result;
	    }
	
	    /**
	     * Creates an array with all falsey values removed. The values `false`, `null`,
	     * `0`, `""`, `undefined`, and `NaN` are falsey.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to compact.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * _.compact([0, 1, false, 2, '', 3]);
	     * // => [1, 2, 3]
	     */
	    function compact(array) {
	      var index = -1,
	          length = array == null ? 0 : array.length,
	          resIndex = 0,
	          result = [];
	
	      while (++index < length) {
	        var value = array[index];
	        if (value) {
	          result[resIndex++] = value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Creates a new array concatenating `array` with any additional arrays
	     * and/or values.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to concatenate.
	     * @param {...*} [values] The values to concatenate.
	     * @returns {Array} Returns the new concatenated array.
	     * @example
	     *
	     * var array = [1];
	     * var other = _.concat(array, 2, [3], [[4]]);
	     *
	     * console.log(other);
	     * // => [1, 2, 3, [4]]
	     *
	     * console.log(array);
	     * // => [1]
	     */
	    function concat() {
	      var length = arguments.length;
	      if (!length) {
	        return [];
	      }
	      var args = Array(length - 1),
	          array = arguments[0],
	          index = length;
	
	      while (index--) {
	        args[index - 1] = arguments[index];
	      }
	      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
	    }
	
	    /**
	     * Creates an array of `array` values not included in the other given arrays
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons. The order and references of result values are
	     * determined by the first array.
	     *
	     * **Note:** Unlike `_.pullAll`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...Array} [values] The values to exclude.
	     * @returns {Array} Returns the new array of filtered values.
	     * @see _.without, _.xor
	     * @example
	     *
	     * _.difference([2, 1], [2, 3]);
	     * // => [1]
	     */
	    var difference = baseRest(function(array, values) {
	      return isArrayLikeObject(array)
	        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
	        : [];
	    });
	
	    /**
	     * This method is like `_.difference` except that it accepts `iteratee` which
	     * is invoked for each element of `array` and `values` to generate the criterion
	     * by which they're compared. The order and references of result values are
	     * determined by the first array. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...Array} [values] The values to exclude.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
	     * // => [1.2]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
	     * // => [{ 'x': 2 }]
	     */
	    var differenceBy = baseRest(function(array, values) {
	      var iteratee = last(values);
	      if (isArrayLikeObject(iteratee)) {
	        iteratee = undefined;
	      }
	      return isArrayLikeObject(array)
	        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
	        : [];
	    });
	
	    /**
	     * This method is like `_.difference` except that it accepts `comparator`
	     * which is invoked to compare elements of `array` to `values`. The order and
	     * references of result values are determined by the first array. The comparator
	     * is invoked with two arguments: (arrVal, othVal).
	     *
	     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...Array} [values] The values to exclude.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     *
	     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
	     * // => [{ 'x': 2, 'y': 1 }]
	     */
	    var differenceWith = baseRest(function(array, values) {
	      var comparator = last(values);
	      if (isArrayLikeObject(comparator)) {
	        comparator = undefined;
	      }
	      return isArrayLikeObject(array)
	        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
	        : [];
	    });
	
	    /**
	     * Creates a slice of `array` with `n` elements dropped from the beginning.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.5.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to drop.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.drop([1, 2, 3]);
	     * // => [2, 3]
	     *
	     * _.drop([1, 2, 3], 2);
	     * // => [3]
	     *
	     * _.drop([1, 2, 3], 5);
	     * // => []
	     *
	     * _.drop([1, 2, 3], 0);
	     * // => [1, 2, 3]
	     */
	    function drop(array, n, guard) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      return baseSlice(array, n < 0 ? 0 : n, length);
	    }
	
	    /**
	     * Creates a slice of `array` with `n` elements dropped from the end.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to drop.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.dropRight([1, 2, 3]);
	     * // => [1, 2]
	     *
	     * _.dropRight([1, 2, 3], 2);
	     * // => [1]
	     *
	     * _.dropRight([1, 2, 3], 5);
	     * // => []
	     *
	     * _.dropRight([1, 2, 3], 0);
	     * // => [1, 2, 3]
	     */
	    function dropRight(array, n, guard) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      n = length - n;
	      return baseSlice(array, 0, n < 0 ? 0 : n);
	    }
	
	    /**
	     * Creates a slice of `array` excluding elements dropped from the end.
	     * Elements are dropped until `predicate` returns falsey. The predicate is
	     * invoked with three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': true },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': false }
	     * ];
	     *
	     * _.dropRightWhile(users, function(o) { return !o.active; });
	     * // => objects for ['barney']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
	     * // => objects for ['barney', 'fred']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.dropRightWhile(users, ['active', false]);
	     * // => objects for ['barney']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.dropRightWhile(users, 'active');
	     * // => objects for ['barney', 'fred', 'pebbles']
	     */
	    function dropRightWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3), true, true)
	        : [];
	    }
	
	    /**
	     * Creates a slice of `array` excluding elements dropped from the beginning.
	     * Elements are dropped until `predicate` returns falsey. The predicate is
	     * invoked with three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': false },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': true }
	     * ];
	     *
	     * _.dropWhile(users, function(o) { return !o.active; });
	     * // => objects for ['pebbles']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.dropWhile(users, { 'user': 'barney', 'active': false });
	     * // => objects for ['fred', 'pebbles']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.dropWhile(users, ['active', false]);
	     * // => objects for ['pebbles']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.dropWhile(users, 'active');
	     * // => objects for ['barney', 'fred', 'pebbles']
	     */
	    function dropWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3), true)
	        : [];
	    }
	
	    /**
	     * Fills elements of `array` with `value` from `start` up to, but not
	     * including, `end`.
	     *
	     * **Note:** This method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.2.0
	     * @category Array
	     * @param {Array} array The array to fill.
	     * @param {*} value The value to fill `array` with.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [1, 2, 3];
	     *
	     * _.fill(array, 'a');
	     * console.log(array);
	     * // => ['a', 'a', 'a']
	     *
	     * _.fill(Array(3), 2);
	     * // => [2, 2, 2]
	     *
	     * _.fill([4, 6, 8, 10], '*', 1, 3);
	     * // => [4, '*', '*', 10]
	     */
	    function fill(array, value, start, end) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return [];
	      }
	      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
	        start = 0;
	        end = length;
	      }
	      return baseFill(array, value, start, end);
	    }
	
	    /**
	     * This method is like `_.find` except that it returns the index of the first
	     * element `predicate` returns truthy for instead of the element itself.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @returns {number} Returns the index of the found element, else `-1`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': false },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': true }
	     * ];
	     *
	     * _.findIndex(users, function(o) { return o.user == 'barney'; });
	     * // => 0
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findIndex(users, { 'user': 'fred', 'active': false });
	     * // => 1
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findIndex(users, ['active', false]);
	     * // => 0
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findIndex(users, 'active');
	     * // => 2
	     */
	    function findIndex(array, predicate, fromIndex) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return -1;
	      }
	      var index = fromIndex == null ? 0 : toInteger(fromIndex);
	      if (index < 0) {
	        index = nativeMax(length + index, 0);
	      }
	      return baseFindIndex(array, getIteratee(predicate, 3), index);
	    }
	
	    /**
	     * This method is like `_.findIndex` except that it iterates over elements
	     * of `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @param {number} [fromIndex=array.length-1] The index to search from.
	     * @returns {number} Returns the index of the found element, else `-1`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': true },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': false }
	     * ];
	     *
	     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
	     * // => 2
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
	     * // => 0
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findLastIndex(users, ['active', false]);
	     * // => 2
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findLastIndex(users, 'active');
	     * // => 0
	     */
	    function findLastIndex(array, predicate, fromIndex) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return -1;
	      }
	      var index = length - 1;
	      if (fromIndex !== undefined) {
	        index = toInteger(fromIndex);
	        index = fromIndex < 0
	          ? nativeMax(length + index, 0)
	          : nativeMin(index, length - 1);
	      }
	      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
	    }
	
	    /**
	     * Flattens `array` a single level deep.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to flatten.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * _.flatten([1, [2, [3, [4]], 5]]);
	     * // => [1, 2, [3, [4]], 5]
	     */
	    function flatten(array) {
	      var length = array == null ? 0 : array.length;
	      return length ? baseFlatten(array, 1) : [];
	    }
	
	    /**
	     * Recursively flattens `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to flatten.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * _.flattenDeep([1, [2, [3, [4]], 5]]);
	     * // => [1, 2, 3, 4, 5]
	     */
	    function flattenDeep(array) {
	      var length = array == null ? 0 : array.length;
	      return length ? baseFlatten(array, INFINITY) : [];
	    }
	
	    /**
	     * Recursively flatten `array` up to `depth` times.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.4.0
	     * @category Array
	     * @param {Array} array The array to flatten.
	     * @param {number} [depth=1] The maximum recursion depth.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * var array = [1, [2, [3, [4]], 5]];
	     *
	     * _.flattenDepth(array, 1);
	     * // => [1, 2, [3, [4]], 5]
	     *
	     * _.flattenDepth(array, 2);
	     * // => [1, 2, 3, [4], 5]
	     */
	    function flattenDepth(array, depth) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return [];
	      }
	      depth = depth === undefined ? 1 : toInteger(depth);
	      return baseFlatten(array, depth);
	    }
	
	    /**
	     * The inverse of `_.toPairs`; this method returns an object composed
	     * from key-value `pairs`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} pairs The key-value pairs.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * _.fromPairs([['a', 1], ['b', 2]]);
	     * // => { 'a': 1, 'b': 2 }
	     */
	    function fromPairs(pairs) {
	      var index = -1,
	          length = pairs == null ? 0 : pairs.length,
	          result = {};
	
	      while (++index < length) {
	        var pair = pairs[index];
	        result[pair[0]] = pair[1];
	      }
	      return result;
	    }
	
	    /**
	     * Gets the first element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @alias first
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {*} Returns the first element of `array`.
	     * @example
	     *
	     * _.head([1, 2, 3]);
	     * // => 1
	     *
	     * _.head([]);
	     * // => undefined
	     */
	    function head(array) {
	      return (array && array.length) ? array[0] : undefined;
	    }
	
	    /**
	     * Gets the index at which the first occurrence of `value` is found in `array`
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons. If `fromIndex` is negative, it's used as the
	     * offset from the end of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.indexOf([1, 2, 1, 2], 2);
	     * // => 1
	     *
	     * // Search from the `fromIndex`.
	     * _.indexOf([1, 2, 1, 2], 2, 2);
	     * // => 3
	     */
	    function indexOf(array, value, fromIndex) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return -1;
	      }
	      var index = fromIndex == null ? 0 : toInteger(fromIndex);
	      if (index < 0) {
	        index = nativeMax(length + index, 0);
	      }
	      return baseIndexOf(array, value, index);
	    }
	
	    /**
	     * Gets all but the last element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.initial([1, 2, 3]);
	     * // => [1, 2]
	     */
	    function initial(array) {
	      var length = array == null ? 0 : array.length;
	      return length ? baseSlice(array, 0, -1) : [];
	    }
	
	    /**
	     * Creates an array of unique values that are included in all given arrays
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons. The order and references of result values are
	     * determined by the first array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @returns {Array} Returns the new array of intersecting values.
	     * @example
	     *
	     * _.intersection([2, 1], [2, 3]);
	     * // => [2]
	     */
	    var intersection = baseRest(function(arrays) {
	      var mapped = arrayMap(arrays, castArrayLikeObject);
	      return (mapped.length && mapped[0] === arrays[0])
	        ? baseIntersection(mapped)
	        : [];
	    });
	
	    /**
	     * This method is like `_.intersection` except that it accepts `iteratee`
	     * which is invoked for each element of each `arrays` to generate the criterion
	     * by which they're compared. The order and references of result values are
	     * determined by the first array. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns the new array of intersecting values.
	     * @example
	     *
	     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
	     * // => [2.1]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 1 }]
	     */
	    var intersectionBy = baseRest(function(arrays) {
	      var iteratee = last(arrays),
	          mapped = arrayMap(arrays, castArrayLikeObject);
	
	      if (iteratee === last(mapped)) {
	        iteratee = undefined;
	      } else {
	        mapped.pop();
	      }
	      return (mapped.length && mapped[0] === arrays[0])
	        ? baseIntersection(mapped, getIteratee(iteratee, 2))
	        : [];
	    });
	
	    /**
	     * This method is like `_.intersection` except that it accepts `comparator`
	     * which is invoked to compare elements of `arrays`. The order and references
	     * of result values are determined by the first array. The comparator is
	     * invoked with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of intersecting values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.intersectionWith(objects, others, _.isEqual);
	     * // => [{ 'x': 1, 'y': 2 }]
	     */
	    var intersectionWith = baseRest(function(arrays) {
	      var comparator = last(arrays),
	          mapped = arrayMap(arrays, castArrayLikeObject);
	
	      comparator = typeof comparator == 'function' ? comparator : undefined;
	      if (comparator) {
	        mapped.pop();
	      }
	      return (mapped.length && mapped[0] === arrays[0])
	        ? baseIntersection(mapped, undefined, comparator)
	        : [];
	    });
	
	    /**
	     * Converts all elements in `array` into a string separated by `separator`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to convert.
	     * @param {string} [separator=','] The element separator.
	     * @returns {string} Returns the joined string.
	     * @example
	     *
	     * _.join(['a', 'b', 'c'], '~');
	     * // => 'a~b~c'
	     */
	    function join(array, separator) {
	      return array == null ? '' : nativeJoin.call(array, separator);
	    }
	
	    /**
	     * Gets the last element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {*} Returns the last element of `array`.
	     * @example
	     *
	     * _.last([1, 2, 3]);
	     * // => 3
	     */
	    function last(array) {
	      var length = array == null ? 0 : array.length;
	      return length ? array[length - 1] : undefined;
	    }
	
	    /**
	     * This method is like `_.indexOf` except that it iterates over elements of
	     * `array` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @param {number} [fromIndex=array.length-1] The index to search from.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.lastIndexOf([1, 2, 1, 2], 2);
	     * // => 3
	     *
	     * // Search from the `fromIndex`.
	     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
	     * // => 1
	     */
	    function lastIndexOf(array, value, fromIndex) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return -1;
	      }
	      var index = length;
	      if (fromIndex !== undefined) {
	        index = toInteger(fromIndex);
	        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
	      }
	      return value === value
	        ? strictLastIndexOf(array, value, index)
	        : baseFindIndex(array, baseIsNaN, index, true);
	    }
	
	    /**
	     * Gets the element at index `n` of `array`. If `n` is negative, the nth
	     * element from the end is returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.11.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=0] The index of the element to return.
	     * @returns {*} Returns the nth element of `array`.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'd'];
	     *
	     * _.nth(array, 1);
	     * // => 'b'
	     *
	     * _.nth(array, -2);
	     * // => 'c';
	     */
	    function nth(array, n) {
	      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
	    }
	
	    /**
	     * Removes all given values from `array` using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
	     * to remove elements from an array by predicate.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {...*} [values] The values to remove.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
	     *
	     * _.pull(array, 'a', 'c');
	     * console.log(array);
	     * // => ['b', 'b']
	     */
	    var pull = baseRest(pullAll);
	
	    /**
	     * This method is like `_.pull` except that it accepts an array of values to remove.
	     *
	     * **Note:** Unlike `_.difference`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
	     *
	     * _.pullAll(array, ['a', 'c']);
	     * console.log(array);
	     * // => ['b', 'b']
	     */
	    function pullAll(array, values) {
	      return (array && array.length && values && values.length)
	        ? basePullAll(array, values)
	        : array;
	    }
	
	    /**
	     * This method is like `_.pullAll` except that it accepts `iteratee` which is
	     * invoked for each element of `array` and `values` to generate the criterion
	     * by which they're compared. The iteratee is invoked with one argument: (value).
	     *
	     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
	     *
	     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
	     * console.log(array);
	     * // => [{ 'x': 2 }]
	     */
	    function pullAllBy(array, values, iteratee) {
	      return (array && array.length && values && values.length)
	        ? basePullAll(array, values, getIteratee(iteratee, 2))
	        : array;
	    }
	
	    /**
	     * This method is like `_.pullAll` except that it accepts `comparator` which
	     * is invoked to compare elements of `array` to `values`. The comparator is
	     * invoked with two arguments: (arrVal, othVal).
	     *
	     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.6.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
	     *
	     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
	     * console.log(array);
	     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
	     */
	    function pullAllWith(array, values, comparator) {
	      return (array && array.length && values && values.length)
	        ? basePullAll(array, values, undefined, comparator)
	        : array;
	    }
	
	    /**
	     * Removes elements from `array` corresponding to `indexes` and returns an
	     * array of removed elements.
	     *
	     * **Note:** Unlike `_.at`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
	     * @returns {Array} Returns the new array of removed elements.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'd'];
	     * var pulled = _.pullAt(array, [1, 3]);
	     *
	     * console.log(array);
	     * // => ['a', 'c']
	     *
	     * console.log(pulled);
	     * // => ['b', 'd']
	     */
	    var pullAt = flatRest(function(array, indexes) {
	      var length = array == null ? 0 : array.length,
	          result = baseAt(array, indexes);
	
	      basePullAt(array, arrayMap(indexes, function(index) {
	        return isIndex(index, length) ? +index : index;
	      }).sort(compareAscending));
	
	      return result;
	    });
	
	    /**
	     * Removes all elements from `array` that `predicate` returns truthy for
	     * and returns an array of the removed elements. The predicate is invoked
	     * with three arguments: (value, index, array).
	     *
	     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
	     * to pull elements from an array by value.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new array of removed elements.
	     * @example
	     *
	     * var array = [1, 2, 3, 4];
	     * var evens = _.remove(array, function(n) {
	     *   return n % 2 == 0;
	     * });
	     *
	     * console.log(array);
	     * // => [1, 3]
	     *
	     * console.log(evens);
	     * // => [2, 4]
	     */
	    function remove(array, predicate) {
	      var result = [];
	      if (!(array && array.length)) {
	        return result;
	      }
	      var index = -1,
	          indexes = [],
	          length = array.length;
	
	      predicate = getIteratee(predicate, 3);
	      while (++index < length) {
	        var value = array[index];
	        if (predicate(value, index, array)) {
	          result.push(value);
	          indexes.push(index);
	        }
	      }
	      basePullAt(array, indexes);
	      return result;
	    }
	
	    /**
	     * Reverses `array` so that the first element becomes the last, the second
	     * element becomes the second to last, and so on.
	     *
	     * **Note:** This method mutates `array` and is based on
	     * [`Array#reverse`](https://mdn.io/Array/reverse).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [1, 2, 3];
	     *
	     * _.reverse(array);
	     * // => [3, 2, 1]
	     *
	     * console.log(array);
	     * // => [3, 2, 1]
	     */
	    function reverse(array) {
	      return array == null ? array : nativeReverse.call(array);
	    }
	
	    /**
	     * Creates a slice of `array` from `start` up to, but not including, `end`.
	     *
	     * **Note:** This method is used instead of
	     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
	     * returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to slice.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns the slice of `array`.
	     */
	    function slice(array, start, end) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return [];
	      }
	      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
	        start = 0;
	        end = length;
	      }
	      else {
	        start = start == null ? 0 : toInteger(start);
	        end = end === undefined ? length : toInteger(end);
	      }
	      return baseSlice(array, start, end);
	    }
	
	    /**
	     * Uses a binary search to determine the lowest index at which `value`
	     * should be inserted into `array` in order to maintain its sort order.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * _.sortedIndex([30, 50], 40);
	     * // => 1
	     */
	    function sortedIndex(array, value) {
	      return baseSortedIndex(array, value);
	    }
	
	    /**
	     * This method is like `_.sortedIndex` except that it accepts `iteratee`
	     * which is invoked for `value` and each element of `array` to compute their
	     * sort ranking. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * var objects = [{ 'x': 4 }, { 'x': 5 }];
	     *
	     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
	     * // => 0
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
	     * // => 0
	     */
	    function sortedIndexBy(array, value, iteratee) {
	      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
	    }
	
	    /**
	     * This method is like `_.indexOf` except that it performs a binary
	     * search on a sorted `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
	     * // => 1
	     */
	    function sortedIndexOf(array, value) {
	      var length = array == null ? 0 : array.length;
	      if (length) {
	        var index = baseSortedIndex(array, value);
	        if (index < length && eq(array[index], value)) {
	          return index;
	        }
	      }
	      return -1;
	    }
	
	    /**
	     * This method is like `_.sortedIndex` except that it returns the highest
	     * index at which `value` should be inserted into `array` in order to
	     * maintain its sort order.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
	     * // => 4
	     */
	    function sortedLastIndex(array, value) {
	      return baseSortedIndex(array, value, true);
	    }
	
	    /**
	     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
	     * which is invoked for `value` and each element of `array` to compute their
	     * sort ranking. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * var objects = [{ 'x': 4 }, { 'x': 5 }];
	     *
	     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
	     * // => 1
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
	     * // => 1
	     */
	    function sortedLastIndexBy(array, value, iteratee) {
	      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
	    }
	
	    /**
	     * This method is like `_.lastIndexOf` except that it performs a binary
	     * search on a sorted `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
	     * // => 3
	     */
	    function sortedLastIndexOf(array, value) {
	      var length = array == null ? 0 : array.length;
	      if (length) {
	        var index = baseSortedIndex(array, value, true) - 1;
	        if (eq(array[index], value)) {
	          return index;
	        }
	      }
	      return -1;
	    }
	
	    /**
	     * This method is like `_.uniq` except that it's designed and optimized
	     * for sorted arrays.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.sortedUniq([1, 1, 2]);
	     * // => [1, 2]
	     */
	    function sortedUniq(array) {
	      return (array && array.length)
	        ? baseSortedUniq(array)
	        : [];
	    }
	
	    /**
	     * This method is like `_.uniqBy` except that it's designed and optimized
	     * for sorted arrays.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
	     * // => [1.1, 2.3]
	     */
	    function sortedUniqBy(array, iteratee) {
	      return (array && array.length)
	        ? baseSortedUniq(array, getIteratee(iteratee, 2))
	        : [];
	    }
	
	    /**
	     * Gets all but the first element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.tail([1, 2, 3]);
	     * // => [2, 3]
	     */
	    function tail(array) {
	      var length = array == null ? 0 : array.length;
	      return length ? baseSlice(array, 1, length) : [];
	    }
	
	    /**
	     * Creates a slice of `array` with `n` elements taken from the beginning.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to take.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.take([1, 2, 3]);
	     * // => [1]
	     *
	     * _.take([1, 2, 3], 2);
	     * // => [1, 2]
	     *
	     * _.take([1, 2, 3], 5);
	     * // => [1, 2, 3]
	     *
	     * _.take([1, 2, 3], 0);
	     * // => []
	     */
	    function take(array, n, guard) {
	      if (!(array && array.length)) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      return baseSlice(array, 0, n < 0 ? 0 : n);
	    }
	
	    /**
	     * Creates a slice of `array` with `n` elements taken from the end.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to take.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.takeRight([1, 2, 3]);
	     * // => [3]
	     *
	     * _.takeRight([1, 2, 3], 2);
	     * // => [2, 3]
	     *
	     * _.takeRight([1, 2, 3], 5);
	     * // => [1, 2, 3]
	     *
	     * _.takeRight([1, 2, 3], 0);
	     * // => []
	     */
	    function takeRight(array, n, guard) {
	      var length = array == null ? 0 : array.length;
	      if (!length) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      n = length - n;
	      return baseSlice(array, n < 0 ? 0 : n, length);
	    }
	
	    /**
	     * Creates a slice of `array` with elements taken from the end. Elements are
	     * taken until `predicate` returns falsey. The predicate is invoked with
	     * three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': true },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': false }
	     * ];
	     *
	     * _.takeRightWhile(users, function(o) { return !o.active; });
	     * // => objects for ['fred', 'pebbles']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
	     * // => objects for ['pebbles']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.takeRightWhile(users, ['active', false]);
	     * // => objects for ['fred', 'pebbles']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.takeRightWhile(users, 'active');
	     * // => []
	     */
	    function takeRightWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3), false, true)
	        : [];
	    }
	
	    /**
	     * Creates a slice of `array` with elements taken from the beginning. Elements
	     * are taken until `predicate` returns falsey. The predicate is invoked with
	     * three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': false },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': true }
	     * ];
	     *
	     * _.takeWhile(users, function(o) { return !o.active; });
	     * // => objects for ['barney', 'fred']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.takeWhile(users, { 'user': 'barney', 'active': false });
	     * // => objects for ['barney']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.takeWhile(users, ['active', false]);
	     * // => objects for ['barney', 'fred']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.takeWhile(users, 'active');
	     * // => []
	     */
	    function takeWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3))
	        : [];
	    }
	
	    /**
	     * Creates an array of unique values, in order, from all given arrays using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @returns {Array} Returns the new array of combined values.
	     * @example
	     *
	     * _.union([2], [1, 2]);
	     * // => [2, 1]
	     */
	    var union = baseRest(function(arrays) {
	      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
	    });
	
	    /**
	     * This method is like `_.union` except that it accepts `iteratee` which is
	     * invoked for each element of each `arrays` to generate the criterion by
	     * which uniqueness is computed. Result values are chosen from the first
	     * array in which the value occurs. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns the new array of combined values.
	     * @example
	     *
	     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
	     * // => [2.1, 1.2]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 1 }, { 'x': 2 }]
	     */
	    var unionBy = baseRest(function(arrays) {
	      var iteratee = last(arrays);
	      if (isArrayLikeObject(iteratee)) {
	        iteratee = undefined;
	      }
	      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
	    });
	
	    /**
	     * This method is like `_.union` except that it accepts `comparator` which
	     * is invoked to compare elements of `arrays`. Result values are chosen from
	     * the first array in which the value occurs. The comparator is invoked
	     * with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of combined values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.unionWith(objects, others, _.isEqual);
	     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
	     */
	    var unionWith = baseRest(function(arrays) {
	      var comparator = last(arrays);
	      comparator = typeof comparator == 'function' ? comparator : undefined;
	      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
	    });
	
	    /**
	     * Creates a duplicate-free version of an array, using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons, in which only the first occurrence of each element
	     * is kept. The order of result values is determined by the order they occur
	     * in the array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.uniq([2, 1, 2]);
	     * // => [2, 1]
	     */
	    function uniq(array) {
	      return (array && array.length) ? baseUniq(array) : [];
	    }
	
	    /**
	     * This method is like `_.uniq` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the criterion by which
	     * uniqueness is computed. The order of result values is determined by the
	     * order they occur in the array. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
	     * // => [2.1, 1.2]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 1 }, { 'x': 2 }]
	     */
	    function uniqBy(array, iteratee) {
	      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
	    }
	
	    /**
	     * This method is like `_.uniq` except that it accepts `comparator` which
	     * is invoked to compare elements of `array`. The order of result values is
	     * determined by the order they occur in the array.The comparator is invoked
	     * with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.uniqWith(objects, _.isEqual);
	     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
	     */
	    function uniqWith(array, comparator) {
	      comparator = typeof comparator == 'function' ? comparator : undefined;
	      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
	    }
	
	    /**
	     * This method is like `_.zip` except that it accepts an array of grouped
	     * elements and creates an array regrouping the elements to their pre-zip
	     * configuration.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.2.0
	     * @category Array
	     * @param {Array} array The array of grouped elements to process.
	     * @returns {Array} Returns the new array of regrouped elements.
	     * @example
	     *
	     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
	     * // => [['a', 1, true], ['b', 2, false]]
	     *
	     * _.unzip(zipped);
	     * // => [['a', 'b'], [1, 2], [true, false]]
	     */
	    function unzip(array) {
	      if (!(array && array.length)) {
	        return [];
	      }
	      var length = 0;
	      array = arrayFilter(array, function(group) {
	        if (isArrayLikeObject(group)) {
	          length = nativeMax(group.length, length);
	          return true;
	        }
	      });
	      return baseTimes(length, function(index) {
	        return arrayMap(array, baseProperty(index));
	      });
	    }
	
	    /**
	     * This method is like `_.unzip` except that it accepts `iteratee` to specify
	     * how regrouped values should be combined. The iteratee is invoked with the
	     * elements of each group: (...group).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.8.0
	     * @category Array
	     * @param {Array} array The array of grouped elements to process.
	     * @param {Function} [iteratee=_.identity] The function to combine
	     *  regrouped values.
	     * @returns {Array} Returns the new array of regrouped elements.
	     * @example
	     *
	     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
	     * // => [[1, 10, 100], [2, 20, 200]]
	     *
	     * _.unzipWith(zipped, _.add);
	     * // => [3, 30, 300]
	     */
	    function unzipWith(array, iteratee) {
	      if (!(array && array.length)) {
	        return [];
	      }
	      var result = unzip(array);
	      if (iteratee == null) {
	        return result;
	      }
	      return arrayMap(result, function(group) {
	        return apply(iteratee, undefined, group);
	      });
	    }
	
	    /**
	     * Creates an array excluding all given values using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * **Note:** Unlike `_.pull`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...*} [values] The values to exclude.
	     * @returns {Array} Returns the new array of filtered values.
	     * @see _.difference, _.xor
	     * @example
	     *
	     * _.without([2, 1, 2, 3], 1, 2);
	     * // => [3]
	     */
	    var without = baseRest(function(array, values) {
	      return isArrayLikeObject(array)
	        ? baseDifference(array, values)
	        : [];
	    });
	
	    /**
	     * Creates an array of unique values that is the
	     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
	     * of the given arrays. The order of result values is determined by the order
	     * they occur in the arrays.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @returns {Array} Returns the new array of filtered values.
	     * @see _.difference, _.without
	     * @example
	     *
	     * _.xor([2, 1], [2, 3]);
	     * // => [1, 3]
	     */
	    var xor = baseRest(function(arrays) {
	      return baseXor(arrayFilter(arrays, isArrayLikeObject));
	    });
	
	    /**
	     * This method is like `_.xor` except that it accepts `iteratee` which is
	     * invoked for each element of each `arrays` to generate the criterion by
	     * which by which they're compared. The order of result values is determined
	     * by the order they occur in the arrays. The iteratee is invoked with one
	     * argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
	     * // => [1.2, 3.4]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 2 }]
	     */
	    var xorBy = baseRest(function(arrays) {
	      var iteratee = last(arrays);
	      if (isArrayLikeObject(iteratee)) {
	        iteratee = undefined;
	      }
	      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
	    });
	
	    /**
	     * This method is like `_.xor` except that it accepts `comparator` which is
	     * invoked to compare elements of `arrays`. The order of result values is
	     * determined by the order they occur in the arrays. The comparator is invoked
	     * with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.xorWith(objects, others, _.isEqual);
	     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
	     */
	    var xorWith = baseRest(function(arrays) {
	      var comparator = last(arrays);
	      comparator = typeof comparator == 'function' ? comparator : undefined;
	      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
	    });
	
	    /**
	     * Creates an array of grouped elements, the first of which contains the
	     * first elements of the given arrays, the second of which contains the
	     * second elements of the given arrays, and so on.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to process.
	     * @returns {Array} Returns the new array of grouped elements.
	     * @example
	     *
	     * _.zip(['a', 'b'], [1, 2], [true, false]);
	     * // => [['a', 1, true], ['b', 2, false]]
	     */
	    var zip = baseRest(unzip);
	
	    /**
	     * This method is like `_.fromPairs` except that it accepts two arrays,
	     * one of property identifiers and one of corresponding values.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.4.0
	     * @category Array
	     * @param {Array} [props=[]] The property identifiers.
	     * @param {Array} [values=[]] The property values.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * _.zipObject(['a', 'b'], [1, 2]);
	     * // => { 'a': 1, 'b': 2 }
	     */
	    function zipObject(props, values) {
	      return baseZipObject(props || [], values || [], assignValue);
	    }
	
	    /**
	     * This method is like `_.zipObject` except that it supports property paths.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.1.0
	     * @category Array
	     * @param {Array} [props=[]] The property identifiers.
	     * @param {Array} [values=[]] The property values.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
	     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
	     */
	    function zipObjectDeep(props, values) {
	      return baseZipObject(props || [], values || [], baseSet);
	    }
	
	    /**
	     * This method is like `_.zip` except that it accepts `iteratee` to specify
	     * how grouped values should be combined. The iteratee is invoked with the
	     * elements of each group: (...group).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.8.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to process.
	     * @param {Function} [iteratee=_.identity] The function to combine
	     *  grouped values.
	     * @returns {Array} Returns the new array of grouped elements.
	     * @example
	     *
	     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
	     *   return a + b + c;
	     * });
	     * // => [111, 222]
	     */
	    var zipWith = baseRest(function(arrays) {
	      var length = arrays.length,
	          iteratee = length > 1 ? arrays[length - 1] : undefined;
	
	      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
	      return unzipWith(arrays, iteratee);
	    });
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
	     * chain sequences enabled. The result of such sequences must be unwrapped
	     * with `_#value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.3.0
	     * @category Seq
	     * @param {*} value The value to wrap.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'age': 36 },
	     *   { 'user': 'fred',    'age': 40 },
	     *   { 'user': 'pebbles', 'age': 1 }
	     * ];
	     *
	     * var youngest = _
	     *   .chain(users)
	     *   .sortBy('age')
	     *   .map(function(o) {
	     *     return o.user + ' is ' + o.age;
	     *   })
	     *   .head()
	     *   .value();
	     * // => 'pebbles is 1'
	     */
	    function chain(value) {
	      var result = lodash(value);
	      result.__chain__ = true;
	      return result;
	    }
	
	    /**
	     * This method invokes `interceptor` and returns `value`. The interceptor
	     * is invoked with one argument; (value). The purpose of this method is to
	     * "tap into" a method chain sequence in order to modify intermediate results.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Seq
	     * @param {*} value The value to provide to `interceptor`.
	     * @param {Function} interceptor The function to invoke.
	     * @returns {*} Returns `value`.
	     * @example
	     *
	     * _([1, 2, 3])
	     *  .tap(function(array) {
	     *    // Mutate input array.
	     *    array.pop();
	     *  })
	     *  .reverse()
	     *  .value();
	     * // => [2, 1]
	     */
	    function tap(value, interceptor) {
	      interceptor(value);
	      return value;
	    }
	
	    /**
	     * This method is like `_.tap` except that it returns the result of `interceptor`.
	     * The purpose of this method is to "pass thru" values replacing intermediate
	     * results in a method chain sequence.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Seq
	     * @param {*} value The value to provide to `interceptor`.
	     * @param {Function} interceptor The function to invoke.
	     * @returns {*} Returns the result of `interceptor`.
	     * @example
	     *
	     * _('  abc  ')
	     *  .chain()
	     *  .trim()
	     *  .thru(function(value) {
	     *    return [value];
	     *  })
	     *  .value();
	     * // => ['abc']
	     */
	    function thru(value, interceptor) {
	      return interceptor(value);
	    }
	
	    /**
	     * This method is the wrapper version of `_.at`.
	     *
	     * @name at
	     * @memberOf _
	     * @since 1.0.0
	     * @category Seq
	     * @param {...(string|string[])} [paths] The property paths to pick.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
	     *
	     * _(object).at(['a[0].b.c', 'a[1]']).value();
	     * // => [3, 4]
	     */
	    var wrapperAt = flatRest(function(paths) {
	      var length = paths.length,
	          start = length ? paths[0] : 0,
	          value = this.__wrapped__,
	          interceptor = function(object) { return baseAt(object, paths); };
	
	      if (length > 1 || this.__actions__.length ||
	          !(value instanceof LazyWrapper) || !isIndex(start)) {
	        return this.thru(interceptor);
	      }
	      value = value.slice(start, +start + (length ? 1 : 0));
	      value.__actions__.push({
	        'func': thru,
	        'args': [interceptor],
	        'thisArg': undefined
	      });
	      return new LodashWrapper(value, this.__chain__).thru(function(array) {
	        if (length && !array.length) {
	          array.push(undefined);
	        }
	        return array;
	      });
	    });
	
	    /**
	     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
	     *
	     * @name chain
	     * @memberOf _
	     * @since 0.1.0
	     * @category Seq
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36 },
	     *   { 'user': 'fred',   'age': 40 }
	     * ];
	     *
	     * // A sequence without explicit chaining.
	     * _(users).head();
	     * // => { 'user': 'barney', 'age': 36 }
	     *
	     * // A sequence with explicit chaining.
	     * _(users)
	     *   .chain()
	     *   .head()
	     *   .pick('user')
	     *   .value();
	     * // => { 'user': 'barney' }
	     */
	    function wrapperChain() {
	      return chain(this);
	    }
	
	    /**
	     * Executes the chain sequence and returns the wrapped result.
	     *
	     * @name commit
	     * @memberOf _
	     * @since 3.2.0
	     * @category Seq
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var array = [1, 2];
	     * var wrapped = _(array).push(3);
	     *
	     * console.log(array);
	     * // => [1, 2]
	     *
	     * wrapped = wrapped.commit();
	     * console.log(array);
	     * // => [1, 2, 3]
	     *
	     * wrapped.last();
	     * // => 3
	     *
	     * console.log(array);
	     * // => [1, 2, 3]
	     */
	    function wrapperCommit() {
	      return new LodashWrapper(this.value(), this.__chain__);
	    }
	
	    /**
	     * Gets the next value on a wrapped object following the
	     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
	     *
	     * @name next
	     * @memberOf _
	     * @since 4.0.0
	     * @category Seq
	     * @returns {Object} Returns the next iterator value.
	     * @example
	     *
	     * var wrapped = _([1, 2]);
	     *
	     * wrapped.next();
	     * // => { 'done': false, 'value': 1 }
	     *
	     * wrapped.next();
	     * // => { 'done': false, 'value': 2 }
	     *
	     * wrapped.next();
	     * // => { 'done': true, 'value': undefined }
	     */
	    function wrapperNext() {
	      if (this.__values__ === undefined) {
	        this.__values__ = toArray(this.value());
	      }
	      var done = this.__index__ >= this.__values__.length,
	          value = done ? undefined : this.__values__[this.__index__++];
	
	      return { 'done': done, 'value': value };
	    }
	
	    /**
	     * Enables the wrapper to be iterable.
	     *
	     * @name Symbol.iterator
	     * @memberOf _
	     * @since 4.0.0
	     * @category Seq
	     * @returns {Object} Returns the wrapper object.
	     * @example
	     *
	     * var wrapped = _([1, 2]);
	     *
	     * wrapped[Symbol.iterator]() === wrapped;
	     * // => true
	     *
	     * Array.from(wrapped);
	     * // => [1, 2]
	     */
	    function wrapperToIterator() {
	      return this;
	    }
	
	    /**
	     * Creates a clone of the chain sequence planting `value` as the wrapped value.
	     *
	     * @name plant
	     * @memberOf _
	     * @since 3.2.0
	     * @category Seq
	     * @param {*} value The value to plant.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var wrapped = _([1, 2]).map(square);
	     * var other = wrapped.plant([3, 4]);
	     *
	     * other.value();
	     * // => [9, 16]
	     *
	     * wrapped.value();
	     * // => [1, 4]
	     */
	    function wrapperPlant(value) {
	      var result,
	          parent = this;
	
	      while (parent instanceof baseLodash) {
	        var clone = wrapperClone(parent);
	        clone.__index__ = 0;
	        clone.__values__ = undefined;
	        if (result) {
	          previous.__wrapped__ = clone;
	        } else {
	          result = clone;
	        }
	        var previous = clone;
	        parent = parent.__wrapped__;
	      }
	      previous.__wrapped__ = value;
	      return result;
	    }
	
	    /**
	     * This method is the wrapper version of `_.reverse`.
	     *
	     * **Note:** This method mutates the wrapped array.
	     *
	     * @name reverse
	     * @memberOf _
	     * @since 0.1.0
	     * @category Seq
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var array = [1, 2, 3];
	     *
	     * _(array).reverse().value()
	     * // => [3, 2, 1]
	     *
	     * console.log(array);
	     * // => [3, 2, 1]
	     */
	    function wrapperReverse() {
	      var value = this.__wrapped__;
	      if (value instanceof LazyWrapper) {
	        var wrapped = value;
	        if (this.__actions__.length) {
	          wrapped = new LazyWrapper(this);
	        }
	        wrapped = wrapped.reverse();
	        wrapped.__actions__.push({
	          'func': thru,
	          'args': [reverse],
	          'thisArg': undefined
	        });
	        return new LodashWrapper(wrapped, this.__chain__);
	      }
	      return this.thru(reverse);
	    }
	
	    /**
	     * Executes the chain sequence to resolve the unwrapped value.
	     *
	     * @name value
	     * @memberOf _
	     * @since 0.1.0
	     * @alias toJSON, valueOf
	     * @category Seq
	     * @returns {*} Returns the resolved unwrapped value.
	     * @example
	     *
	     * _([1, 2, 3]).value();
	     * // => [1, 2, 3]
	     */
	    function wrapperValue() {
	      return baseWrapperValue(this.__wrapped__, this.__actions__);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an object composed of keys generated from the results of running
	     * each element of `collection` thru `iteratee`. The corresponding value of
	     * each key is the number of times the key was returned by `iteratee`. The
	     * iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.5.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
	     * @returns {Object} Returns the composed aggregate object.
	     * @example
	     *
	     * _.countBy([6.1, 4.2, 6.3], Math.floor);
	     * // => { '4': 1, '6': 2 }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.countBy(['one', 'two', 'three'], 'length');
	     * // => { '3': 2, '5': 1 }
	     */
	    var countBy = createAggregator(function(result, value, key) {
	      if (hasOwnProperty.call(result, key)) {
	        ++result[key];
	      } else {
	        baseAssignValue(result, key, 1);
	      }
	    });
	
	    /**
	     * Checks if `predicate` returns truthy for **all** elements of `collection`.
	     * Iteration is stopped once `predicate` returns falsey. The predicate is
	     * invoked with three arguments: (value, index|key, collection).
	     *
	     * **Note:** This method returns `true` for
	     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
	     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
	     * elements of empty collections.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {boolean} Returns `true` if all elements pass the predicate check,
	     *  else `false`.
	     * @example
	     *
	     * _.every([true, 1, null, 'yes'], Boolean);
	     * // => false
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': false },
	     *   { 'user': 'fred',   'age': 40, 'active': false }
	     * ];
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.every(users, { 'user': 'barney', 'active': false });
	     * // => false
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.every(users, ['active', false]);
	     * // => true
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.every(users, 'active');
	     * // => false
	     */
	    function every(collection, predicate, guard) {
	      var func = isArray(collection) ? arrayEvery : baseEvery;
	      if (guard && isIterateeCall(collection, predicate, guard)) {
	        predicate = undefined;
	      }
	      return func(collection, getIteratee(predicate, 3));
	    }
	
	    /**
	     * Iterates over elements of `collection`, returning an array of all elements
	     * `predicate` returns truthy for. The predicate is invoked with three
	     * arguments: (value, index|key, collection).
	     *
	     * **Note:** Unlike `_.remove`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new filtered array.
	     * @see _.reject
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': true },
	     *   { 'user': 'fred',   'age': 40, 'active': false }
	     * ];
	     *
	     * _.filter(users, function(o) { return !o.active; });
	     * // => objects for ['fred']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.filter(users, { 'age': 36, 'active': true });
	     * // => objects for ['barney']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.filter(users, ['active', false]);
	     * // => objects for ['fred']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.filter(users, 'active');
	     * // => objects for ['barney']
	     */
	    function filter(collection, predicate) {
	      var func = isArray(collection) ? arrayFilter : baseFilter;
	      return func(collection, getIteratee(predicate, 3));
	    }
	
	    /**
	     * Iterates over elements of `collection`, returning the first element
	     * `predicate` returns truthy for. The predicate is invoked with three
	     * arguments: (value, index|key, collection).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @returns {*} Returns the matched element, else `undefined`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'age': 36, 'active': true },
	     *   { 'user': 'fred',    'age': 40, 'active': false },
	     *   { 'user': 'pebbles', 'age': 1,  'active': true }
	     * ];
	     *
	     * _.find(users, function(o) { return o.age < 40; });
	     * // => object for 'barney'
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.find(users, { 'age': 1, 'active': true });
	     * // => object for 'pebbles'
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.find(users, ['active', false]);
	     * // => object for 'fred'
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.find(users, 'active');
	     * // => object for 'barney'
	     */
	    var find = createFind(findIndex);
	
	    /**
	     * This method is like `_.find` except that it iterates over elements of
	     * `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @param {number} [fromIndex=collection.length-1] The index to search from.
	     * @returns {*} Returns the matched element, else `undefined`.
	     * @example
	     *
	     * _.findLast([1, 2, 3, 4], function(n) {
	     *   return n % 2 == 1;
	     * });
	     * // => 3
	     */
	    var findLast = createFind(findLastIndex);
	
	    /**
	     * Creates a flattened array of values by running each element in `collection`
	     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
	     * with three arguments: (value, index|key, collection).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * function duplicate(n) {
	     *   return [n, n];
	     * }
	     *
	     * _.flatMap([1, 2], duplicate);
	     * // => [1, 1, 2, 2]
	     */
	    function flatMap(collection, iteratee) {
	      return baseFlatten(map(collection, iteratee), 1);
	    }
	
	    /**
	     * This method is like `_.flatMap` except that it recursively flattens the
	     * mapped results.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * function duplicate(n) {
	     *   return [[[n, n]]];
	     * }
	     *
	     * _.flatMapDeep([1, 2], duplicate);
	     * // => [1, 1, 2, 2]
	     */
	    function flatMapDeep(collection, iteratee) {
	      return baseFlatten(map(collection, iteratee), INFINITY);
	    }
	
	    /**
	     * This method is like `_.flatMap` except that it recursively flattens the
	     * mapped results up to `depth` times.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @param {number} [depth=1] The maximum recursion depth.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * function duplicate(n) {
	     *   return [[[n, n]]];
	     * }
	     *
	     * _.flatMapDepth([1, 2], duplicate, 2);
	     * // => [[1, 1], [2, 2]]
	     */
	    function flatMapDepth(collection, iteratee, depth) {
	      depth = depth === undefined ? 1 : toInteger(depth);
	      return baseFlatten(map(collection, iteratee), depth);
	    }
	
	    /**
	     * Iterates over elements of `collection` and invokes `iteratee` for each element.
	     * The iteratee is invoked with three arguments: (value, index|key, collection).
	     * Iteratee functions may exit iteration early by explicitly returning `false`.
	     *
	     * **Note:** As with other "Collections" methods, objects with a "length"
	     * property are iterated like arrays. To avoid this behavior use `_.forIn`
	     * or `_.forOwn` for object iteration.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @alias each
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     * @see _.forEachRight
	     * @example
	     *
	     * _.forEach([1, 2], function(value) {
	     *   console.log(value);
	     * });
	     * // => Logs `1` then `2`.
	     *
	     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
	     */
	    function forEach(collection, iteratee) {
	      var func = isArray(collection) ? arrayEach : baseEach;
	      return func(collection, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * This method is like `_.forEach` except that it iterates over elements of
	     * `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @alias eachRight
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     * @see _.forEach
	     * @example
	     *
	     * _.forEachRight([1, 2], function(value) {
	     *   console.log(value);
	     * });
	     * // => Logs `2` then `1`.
	     */
	    function forEachRight(collection, iteratee) {
	      var func = isArray(collection) ? arrayEachRight : baseEachRight;
	      return func(collection, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * Creates an object composed of keys generated from the results of running
	     * each element of `collection` thru `iteratee`. The order of grouped values
	     * is determined by the order they occur in `collection`. The corresponding
	     * value of each key is an array of elements responsible for generating the
	     * key. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
	     * @returns {Object} Returns the composed aggregate object.
	     * @example
	     *
	     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
	     * // => { '4': [4.2], '6': [6.1, 6.3] }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.groupBy(['one', 'two', 'three'], 'length');
	     * // => { '3': ['one', 'two'], '5': ['three'] }
	     */
	    var groupBy = createAggregator(function(result, value, key) {
	      if (hasOwnProperty.call(result, key)) {
	        result[key].push(value);
	      } else {
	        baseAssignValue(result, key, [value]);
	      }
	    });
	
	    /**
	     * Checks if `value` is in `collection`. If `collection` is a string, it's
	     * checked for a substring of `value`, otherwise
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * is used for equality comparisons. If `fromIndex` is negative, it's used as
	     * the offset from the end of `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object|string} collection The collection to inspect.
	     * @param {*} value The value to search for.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
	     * @returns {boolean} Returns `true` if `value` is found, else `false`.
	     * @example
	     *
	     * _.includes([1, 2, 3], 1);
	     * // => true
	     *
	     * _.includes([1, 2, 3], 1, 2);
	     * // => false
	     *
	     * _.includes({ 'a': 1, 'b': 2 }, 1);
	     * // => true
	     *
	     * _.includes('abcd', 'bc');
	     * // => true
	     */
	    function includes(collection, value, fromIndex, guard) {
	      collection = isArrayLike(collection) ? collection : values(collection);
	      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
	
	      var length = collection.length;
	      if (fromIndex < 0) {
	        fromIndex = nativeMax(length + fromIndex, 0);
	      }
	      return isString(collection)
	        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
	        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
	    }
	
	    /**
	     * Invokes the method at `path` of each element in `collection`, returning
	     * an array of the results of each invoked method. Any additional arguments
	     * are provided to each invoked method. If `path` is a function, it's invoked
	     * for, and `this` bound to, each element in `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Array|Function|string} path The path of the method to invoke or
	     *  the function invoked per iteration.
	     * @param {...*} [args] The arguments to invoke each method with.
	     * @returns {Array} Returns the array of results.
	     * @example
	     *
	     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
	     * // => [[1, 5, 7], [1, 2, 3]]
	     *
	     * _.invokeMap([123, 456], String.prototype.split, '');
	     * // => [['1', '2', '3'], ['4', '5', '6']]
	     */
	    var invokeMap = baseRest(function(collection, path, args) {
	      var index = -1,
	          isFunc = typeof path == 'function',
	          result = isArrayLike(collection) ? Array(collection.length) : [];
	
	      baseEach(collection, function(value) {
	        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
	      });
	      return result;
	    });
	
	    /**
	     * Creates an object composed of keys generated from the results of running
	     * each element of `collection` thru `iteratee`. The corresponding value of
	     * each key is the last element responsible for generating the key. The
	     * iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
	     * @returns {Object} Returns the composed aggregate object.
	     * @example
	     *
	     * var array = [
	     *   { 'dir': 'left', 'code': 97 },
	     *   { 'dir': 'right', 'code': 100 }
	     * ];
	     *
	     * _.keyBy(array, function(o) {
	     *   return String.fromCharCode(o.code);
	     * });
	     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
	     *
	     * _.keyBy(array, 'dir');
	     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
	     */
	    var keyBy = createAggregator(function(result, value, key) {
	      baseAssignValue(result, key, value);
	    });
	
	    /**
	     * Creates an array of values by running each element in `collection` thru
	     * `iteratee`. The iteratee is invoked with three arguments:
	     * (value, index|key, collection).
	     *
	     * Many lodash methods are guarded to work as iteratees for methods like
	     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
	     *
	     * The guarded methods are:
	     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
	     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
	     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
	     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new mapped array.
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * _.map([4, 8], square);
	     * // => [16, 64]
	     *
	     * _.map({ 'a': 4, 'b': 8 }, square);
	     * // => [16, 64] (iteration order is not guaranteed)
	     *
	     * var users = [
	     *   { 'user': 'barney' },
	     *   { 'user': 'fred' }
	     * ];
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.map(users, 'user');
	     * // => ['barney', 'fred']
	     */
	    function map(collection, iteratee) {
	      var func = isArray(collection) ? arrayMap : baseMap;
	      return func(collection, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * This method is like `_.sortBy` except that it allows specifying the sort
	     * orders of the iteratees to sort by. If `orders` is unspecified, all values
	     * are sorted in ascending order. Otherwise, specify an order of "desc" for
	     * descending or "asc" for ascending sort order of corresponding values.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
	     *  The iteratees to sort by.
	     * @param {string[]} [orders] The sort orders of `iteratees`.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
	     * @returns {Array} Returns the new sorted array.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'fred',   'age': 48 },
	     *   { 'user': 'barney', 'age': 34 },
	     *   { 'user': 'fred',   'age': 40 },
	     *   { 'user': 'barney', 'age': 36 }
	     * ];
	     *
	     * // Sort by `user` in ascending order and by `age` in descending order.
	     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
	     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
	     */
	    function orderBy(collection, iteratees, orders, guard) {
	      if (collection == null) {
	        return [];
	      }
	      if (!isArray(iteratees)) {
	        iteratees = iteratees == null ? [] : [iteratees];
	      }
	      orders = guard ? undefined : orders;
	      if (!isArray(orders)) {
	        orders = orders == null ? [] : [orders];
	      }
	      return baseOrderBy(collection, iteratees, orders);
	    }
	
	    /**
	     * Creates an array of elements split into two groups, the first of which
	     * contains elements `predicate` returns truthy for, the second of which
	     * contains elements `predicate` returns falsey for. The predicate is
	     * invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the array of grouped elements.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'age': 36, 'active': false },
	     *   { 'user': 'fred',    'age': 40, 'active': true },
	     *   { 'user': 'pebbles', 'age': 1,  'active': false }
	     * ];
	     *
	     * _.partition(users, function(o) { return o.active; });
	     * // => objects for [['fred'], ['barney', 'pebbles']]
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.partition(users, { 'age': 1, 'active': false });
	     * // => objects for [['pebbles'], ['barney', 'fred']]
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.partition(users, ['active', false]);
	     * // => objects for [['barney', 'pebbles'], ['fred']]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.partition(users, 'active');
	     * // => objects for [['fred'], ['barney', 'pebbles']]
	     */
	    var partition = createAggregator(function(result, value, key) {
	      result[key ? 0 : 1].push(value);
	    }, function() { return [[], []]; });
	
	    /**
	     * Reduces `collection` to a value which is the accumulated result of running
	     * each element in `collection` thru `iteratee`, where each successive
	     * invocation is supplied the return value of the previous. If `accumulator`
	     * is not given, the first element of `collection` is used as the initial
	     * value. The iteratee is invoked with four arguments:
	     * (accumulator, value, index|key, collection).
	     *
	     * Many lodash methods are guarded to work as iteratees for methods like
	     * `_.reduce`, `_.reduceRight`, and `_.transform`.
	     *
	     * The guarded methods are:
	     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
	     * and `sortBy`
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @param {*} [accumulator] The initial value.
	     * @returns {*} Returns the accumulated value.
	     * @see _.reduceRight
	     * @example
	     *
	     * _.reduce([1, 2], function(sum, n) {
	     *   return sum + n;
	     * }, 0);
	     * // => 3
	     *
	     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
	     *   (result[value] || (result[value] = [])).push(key);
	     *   return result;
	     * }, {});
	     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
	     */
	    function reduce(collection, iteratee, accumulator) {
	      var func = isArray(collection) ? arrayReduce : baseReduce,
	          initAccum = arguments.length < 3;
	
	      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
	    }
	
	    /**
	     * This method is like `_.reduce` except that it iterates over elements of
	     * `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @param {*} [accumulator] The initial value.
	     * @returns {*} Returns the accumulated value.
	     * @see _.reduce
	     * @example
	     *
	     * var array = [[0, 1], [2, 3], [4, 5]];
	     *
	     * _.reduceRight(array, function(flattened, other) {
	     *   return flattened.concat(other);
	     * }, []);
	     * // => [4, 5, 2, 3, 0, 1]
	     */
	    function reduceRight(collection, iteratee, accumulator) {
	      var func = isArray(collection) ? arrayReduceRight : baseReduce,
	          initAccum = arguments.length < 3;
	
	      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
	    }
	
	    /**
	     * The opposite of `_.filter`; this method returns the elements of `collection`
	     * that `predicate` does **not** return truthy for.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new filtered array.
	     * @see _.filter
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': false },
	     *   { 'user': 'fred',   'age': 40, 'active': true }
	     * ];
	     *
	     * _.reject(users, function(o) { return !o.active; });
	     * // => objects for ['fred']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.reject(users, { 'age': 40, 'active': true });
	     * // => objects for ['barney']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.reject(users, ['active', false]);
	     * // => objects for ['fred']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.reject(users, 'active');
	     * // => objects for ['barney']
	     */
	    function reject(collection, predicate) {
	      var func = isArray(collection) ? arrayFilter : baseFilter;
	      return func(collection, negate(getIteratee(predicate, 3)));
	    }
	
	    /**
	     * Gets a random element from `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to sample.
	     * @returns {*} Returns the random element.
	     * @example
	     *
	     * _.sample([1, 2, 3, 4]);
	     * // => 2
	     */
	    function sample(collection) {
	      var func = isArray(collection) ? arraySample : baseSample;
	      return func(collection);
	    }
	
	    /**
	     * Gets `n` random elements at unique keys from `collection` up to the
	     * size of `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to sample.
	     * @param {number} [n=1] The number of elements to sample.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the random elements.
	     * @example
	     *
	     * _.sampleSize([1, 2, 3], 2);
	     * // => [3, 1]
	     *
	     * _.sampleSize([1, 2, 3], 4);
	     * // => [2, 3, 1]
	     */
	    function sampleSize(collection, n, guard) {
	      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
	        n = 1;
	      } else {
	        n = toInteger(n);
	      }
	      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
	      return func(collection, n);
	    }
	
	    /**
	     * Creates an array of shuffled values, using a version of the
	     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to shuffle.
	     * @returns {Array} Returns the new shuffled array.
	     * @example
	     *
	     * _.shuffle([1, 2, 3, 4]);
	     * // => [4, 1, 3, 2]
	     */
	    function shuffle(collection) {
	      var func = isArray(collection) ? arrayShuffle : baseShuffle;
	      return func(collection);
	    }
	
	    /**
	     * Gets the size of `collection` by returning its length for array-like
	     * values or the number of own enumerable string keyed properties for objects.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object|string} collection The collection to inspect.
	     * @returns {number} Returns the collection size.
	     * @example
	     *
	     * _.size([1, 2, 3]);
	     * // => 3
	     *
	     * _.size({ 'a': 1, 'b': 2 });
	     * // => 2
	     *
	     * _.size('pebbles');
	     * // => 7
	     */
	    function size(collection) {
	      if (collection == null) {
	        return 0;
	      }
	      if (isArrayLike(collection)) {
	        return isString(collection) ? stringSize(collection) : collection.length;
	      }
	      var tag = getTag(collection);
	      if (tag == mapTag || tag == setTag) {
	        return collection.size;
	      }
	      return baseKeys(collection).length;
	    }
	
	    /**
	     * Checks if `predicate` returns truthy for **any** element of `collection`.
	     * Iteration is stopped once `predicate` returns truthy. The predicate is
	     * invoked with three arguments: (value, index|key, collection).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {boolean} Returns `true` if any element passes the predicate check,
	     *  else `false`.
	     * @example
	     *
	     * _.some([null, 0, 'yes', false], Boolean);
	     * // => true
	     *
	     * var users = [
	     *   { 'user': 'barney', 'active': true },
	     *   { 'user': 'fred',   'active': false }
	     * ];
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.some(users, { 'user': 'barney', 'active': false });
	     * // => false
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.some(users, ['active', false]);
	     * // => true
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.some(users, 'active');
	     * // => true
	     */
	    function some(collection, predicate, guard) {
	      var func = isArray(collection) ? arraySome : baseSome;
	      if (guard && isIterateeCall(collection, predicate, guard)) {
	        predicate = undefined;
	      }
	      return func(collection, getIteratee(predicate, 3));
	    }
	
	    /**
	     * Creates an array of elements, sorted in ascending order by the results of
	     * running each element in a collection thru each iteratee. This method
	     * performs a stable sort, that is, it preserves the original sort order of
	     * equal elements. The iteratees are invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {...(Function|Function[])} [iteratees=[_.identity]]
	     *  The iteratees to sort by.
	     * @returns {Array} Returns the new sorted array.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'fred',   'age': 48 },
	     *   { 'user': 'barney', 'age': 36 },
	     *   { 'user': 'fred',   'age': 40 },
	     *   { 'user': 'barney', 'age': 34 }
	     * ];
	     *
	     * _.sortBy(users, [function(o) { return o.user; }]);
	     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
	     *
	     * _.sortBy(users, ['user', 'age']);
	     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
	     */
	    var sortBy = baseRest(function(collection, iteratees) {
	      if (collection == null) {
	        return [];
	      }
	      var length = iteratees.length;
	      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
	        iteratees = [];
	      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
	        iteratees = [iteratees[0]];
	      }
	      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
	    });
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Gets the timestamp of the number of milliseconds that have elapsed since
	     * the Unix epoch (1 January 1970 00:00:00 UTC).
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Date
	     * @returns {number} Returns the timestamp.
	     * @example
	     *
	     * _.defer(function(stamp) {
	     *   console.log(_.now() - stamp);
	     * }, _.now());
	     * // => Logs the number of milliseconds it took for the deferred invocation.
	     */
	    var now = ctxNow || function() {
	      return root.Date.now();
	    };
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * The opposite of `_.before`; this method creates a function that invokes
	     * `func` once it's called `n` or more times.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {number} n The number of calls before `func` is invoked.
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new restricted function.
	     * @example
	     *
	     * var saves = ['profile', 'settings'];
	     *
	     * var done = _.after(saves.length, function() {
	     *   console.log('done saving!');
	     * });
	     *
	     * _.forEach(saves, function(type) {
	     *   asyncSave({ 'type': type, 'complete': done });
	     * });
	     * // => Logs 'done saving!' after the two async saves have completed.
	     */
	    function after(n, func) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      n = toInteger(n);
	      return function() {
	        if (--n < 1) {
	          return func.apply(this, arguments);
	        }
	      };
	    }
	
	    /**
	     * Creates a function that invokes `func`, with up to `n` arguments,
	     * ignoring any additional arguments.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} func The function to cap arguments for.
	     * @param {number} [n=func.length] The arity cap.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the new capped function.
	     * @example
	     *
	     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
	     * // => [6, 8, 10]
	     */
	    function ary(func, n, guard) {
	      n = guard ? undefined : n;
	      n = (func && n == null) ? func.length : n;
	      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
	    }
	
	    /**
	     * Creates a function that invokes `func`, with the `this` binding and arguments
	     * of the created function, while it's called less than `n` times. Subsequent
	     * calls to the created function return the result of the last `func` invocation.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {number} n The number of calls at which `func` is no longer invoked.
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new restricted function.
	     * @example
	     *
	     * jQuery(element).on('click', _.before(5, addContactToList));
	     * // => Allows adding up to 4 contacts to the list.
	     */
	    function before(n, func) {
	      var result;
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      n = toInteger(n);
	      return function() {
	        if (--n > 0) {
	          result = func.apply(this, arguments);
	        }
	        if (n <= 1) {
	          func = undefined;
	        }
	        return result;
	      };
	    }
	
	    /**
	     * Creates a function that invokes `func` with the `this` binding of `thisArg`
	     * and `partials` prepended to the arguments it receives.
	     *
	     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
	     * may be used as a placeholder for partially applied arguments.
	     *
	     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
	     * property of bound functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to bind.
	     * @param {*} thisArg The `this` binding of `func`.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new bound function.
	     * @example
	     *
	     * function greet(greeting, punctuation) {
	     *   return greeting + ' ' + this.user + punctuation;
	     * }
	     *
	     * var object = { 'user': 'fred' };
	     *
	     * var bound = _.bind(greet, object, 'hi');
	     * bound('!');
	     * // => 'hi fred!'
	     *
	     * // Bound with placeholders.
	     * var bound = _.bind(greet, object, _, '!');
	     * bound('hi');
	     * // => 'hi fred!'
	     */
	    var bind = baseRest(function(func, thisArg, partials) {
	      var bitmask = WRAP_BIND_FLAG;
	      if (partials.length) {
	        var holders = replaceHolders(partials, getHolder(bind));
	        bitmask |= WRAP_PARTIAL_FLAG;
	      }
	      return createWrap(func, bitmask, thisArg, partials, holders);
	    });
	
	    /**
	     * Creates a function that invokes the method at `object[key]` with `partials`
	     * prepended to the arguments it receives.
	     *
	     * This method differs from `_.bind` by allowing bound functions to reference
	     * methods that may be redefined or don't yet exist. See
	     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
	     * for more details.
	     *
	     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for partially applied arguments.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.10.0
	     * @category Function
	     * @param {Object} object The object to invoke the method on.
	     * @param {string} key The key of the method.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new bound function.
	     * @example
	     *
	     * var object = {
	     *   'user': 'fred',
	     *   'greet': function(greeting, punctuation) {
	     *     return greeting + ' ' + this.user + punctuation;
	     *   }
	     * };
	     *
	     * var bound = _.bindKey(object, 'greet', 'hi');
	     * bound('!');
	     * // => 'hi fred!'
	     *
	     * object.greet = function(greeting, punctuation) {
	     *   return greeting + 'ya ' + this.user + punctuation;
	     * };
	     *
	     * bound('!');
	     * // => 'hiya fred!'
	     *
	     * // Bound with placeholders.
	     * var bound = _.bindKey(object, 'greet', _, '!');
	     * bound('hi');
	     * // => 'hiya fred!'
	     */
	    var bindKey = baseRest(function(object, key, partials) {
	      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
	      if (partials.length) {
	        var holders = replaceHolders(partials, getHolder(bindKey));
	        bitmask |= WRAP_PARTIAL_FLAG;
	      }
	      return createWrap(key, bitmask, object, partials, holders);
	    });
	
	    /**
	     * Creates a function that accepts arguments of `func` and either invokes
	     * `func` returning its result, if at least `arity` number of arguments have
	     * been provided, or returns a function that accepts the remaining `func`
	     * arguments, and so on. The arity of `func` may be specified if `func.length`
	     * is not sufficient.
	     *
	     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
	     * may be used as a placeholder for provided arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of curried functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Function
	     * @param {Function} func The function to curry.
	     * @param {number} [arity=func.length] The arity of `func`.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the new curried function.
	     * @example
	     *
	     * var abc = function(a, b, c) {
	     *   return [a, b, c];
	     * };
	     *
	     * var curried = _.curry(abc);
	     *
	     * curried(1)(2)(3);
	     * // => [1, 2, 3]
	     *
	     * curried(1, 2)(3);
	     * // => [1, 2, 3]
	     *
	     * curried(1, 2, 3);
	     * // => [1, 2, 3]
	     *
	     * // Curried with placeholders.
	     * curried(1)(_, 3)(2);
	     * // => [1, 2, 3]
	     */
	    function curry(func, arity, guard) {
	      arity = guard ? undefined : arity;
	      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
	      result.placeholder = curry.placeholder;
	      return result;
	    }
	
	    /**
	     * This method is like `_.curry` except that arguments are applied to `func`
	     * in the manner of `_.partialRight` instead of `_.partial`.
	     *
	     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for provided arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of curried functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} func The function to curry.
	     * @param {number} [arity=func.length] The arity of `func`.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the new curried function.
	     * @example
	     *
	     * var abc = function(a, b, c) {
	     *   return [a, b, c];
	     * };
	     *
	     * var curried = _.curryRight(abc);
	     *
	     * curried(3)(2)(1);
	     * // => [1, 2, 3]
	     *
	     * curried(2, 3)(1);
	     * // => [1, 2, 3]
	     *
	     * curried(1, 2, 3);
	     * // => [1, 2, 3]
	     *
	     * // Curried with placeholders.
	     * curried(3)(1, _)(2);
	     * // => [1, 2, 3]
	     */
	    function curryRight(func, arity, guard) {
	      arity = guard ? undefined : arity;
	      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
	      result.placeholder = curryRight.placeholder;
	      return result;
	    }
	
	    /**
	     * Creates a debounced function that delays invoking `func` until after `wait`
	     * milliseconds have elapsed since the last time the debounced function was
	     * invoked. The debounced function comes with a `cancel` method to cancel
	     * delayed `func` invocations and a `flush` method to immediately invoke them.
	     * Provide `options` to indicate whether `func` should be invoked on the
	     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
	     * with the last arguments provided to the debounced function. Subsequent
	     * calls to the debounced function return the result of the last `func`
	     * invocation.
	     *
	     * **Note:** If `leading` and `trailing` options are `true`, `func` is
	     * invoked on the trailing edge of the timeout only if the debounced function
	     * is invoked more than once during the `wait` timeout.
	     *
	     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	     *
	     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	     * for details over the differences between `_.debounce` and `_.throttle`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to debounce.
	     * @param {number} [wait=0] The number of milliseconds to delay.
	     * @param {Object} [options={}] The options object.
	     * @param {boolean} [options.leading=false]
	     *  Specify invoking on the leading edge of the timeout.
	     * @param {number} [options.maxWait]
	     *  The maximum time `func` is allowed to be delayed before it's invoked.
	     * @param {boolean} [options.trailing=true]
	     *  Specify invoking on the trailing edge of the timeout.
	     * @returns {Function} Returns the new debounced function.
	     * @example
	     *
	     * // Avoid costly calculations while the window size is in flux.
	     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
	     *
	     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
	     * jQuery(element).on('click', _.debounce(sendMail, 300, {
	     *   'leading': true,
	     *   'trailing': false
	     * }));
	     *
	     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
	     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
	     * var source = new EventSource('/stream');
	     * jQuery(source).on('message', debounced);
	     *
	     * // Cancel the trailing debounced invocation.
	     * jQuery(window).on('popstate', debounced.cancel);
	     */
	    function debounce(func, wait, options) {
	      var lastArgs,
	          lastThis,
	          maxWait,
	          result,
	          timerId,
	          lastCallTime,
	          lastInvokeTime = 0,
	          leading = false,
	          maxing = false,
	          trailing = true;
	
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      wait = toNumber(wait) || 0;
	      if (isObject(options)) {
	        leading = !!options.leading;
	        maxing = 'maxWait' in options;
	        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
	        trailing = 'trailing' in options ? !!options.trailing : trailing;
	      }
	
	      function invokeFunc(time) {
	        var args = lastArgs,
	            thisArg = lastThis;
	
	        lastArgs = lastThis = undefined;
	        lastInvokeTime = time;
	        result = func.apply(thisArg, args);
	        return result;
	      }
	
	      function leadingEdge(time) {
	        // Reset any `maxWait` timer.
	        lastInvokeTime = time;
	        // Start the timer for the trailing edge.
	        timerId = setTimeout(timerExpired, wait);
	        // Invoke the leading edge.
	        return leading ? invokeFunc(time) : result;
	      }
	
	      function remainingWait(time) {
	        var timeSinceLastCall = time - lastCallTime,
	            timeSinceLastInvoke = time - lastInvokeTime,
	            result = wait - timeSinceLastCall;
	
	        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
	      }
	
	      function shouldInvoke(time) {
	        var timeSinceLastCall = time - lastCallTime,
	            timeSinceLastInvoke = time - lastInvokeTime;
	
	        // Either this is the first call, activity has stopped and we're at the
	        // trailing edge, the system time has gone backwards and we're treating
	        // it as the trailing edge, or we've hit the `maxWait` limit.
	        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
	          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
	      }
	
	      function timerExpired() {
	        var time = now();
	        if (shouldInvoke(time)) {
	          return trailingEdge(time);
	        }
	        // Restart the timer.
	        timerId = setTimeout(timerExpired, remainingWait(time));
	      }
	
	      function trailingEdge(time) {
	        timerId = undefined;
	
	        // Only invoke if we have `lastArgs` which means `func` has been
	        // debounced at least once.
	        if (trailing && lastArgs) {
	          return invokeFunc(time);
	        }
	        lastArgs = lastThis = undefined;
	        return result;
	      }
	
	      function cancel() {
	        if (timerId !== undefined) {
	          clearTimeout(timerId);
	        }
	        lastInvokeTime = 0;
	        lastArgs = lastCallTime = lastThis = timerId = undefined;
	      }
	
	      function flush() {
	        return timerId === undefined ? result : trailingEdge(now());
	      }
	
	      function debounced() {
	        var time = now(),
	            isInvoking = shouldInvoke(time);
	
	        lastArgs = arguments;
	        lastThis = this;
	        lastCallTime = time;
	
	        if (isInvoking) {
	          if (timerId === undefined) {
	            return leadingEdge(lastCallTime);
	          }
	          if (maxing) {
	            // Handle invocations in a tight loop.
	            timerId = setTimeout(timerExpired, wait);
	            return invokeFunc(lastCallTime);
	          }
	        }
	        if (timerId === undefined) {
	          timerId = setTimeout(timerExpired, wait);
	        }
	        return result;
	      }
	      debounced.cancel = cancel;
	      debounced.flush = flush;
	      return debounced;
	    }
	
	    /**
	     * Defers invoking the `func` until the current call stack has cleared. Any
	     * additional arguments are provided to `func` when it's invoked.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to defer.
	     * @param {...*} [args] The arguments to invoke `func` with.
	     * @returns {number} Returns the timer id.
	     * @example
	     *
	     * _.defer(function(text) {
	     *   console.log(text);
	     * }, 'deferred');
	     * // => Logs 'deferred' after one millisecond.
	     */
	    var defer = baseRest(function(func, args) {
	      return baseDelay(func, 1, args);
	    });
	
	    /**
	     * Invokes `func` after `wait` milliseconds. Any additional arguments are
	     * provided to `func` when it's invoked.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to delay.
	     * @param {number} wait The number of milliseconds to delay invocation.
	     * @param {...*} [args] The arguments to invoke `func` with.
	     * @returns {number} Returns the timer id.
	     * @example
	     *
	     * _.delay(function(text) {
	     *   console.log(text);
	     * }, 1000, 'later');
	     * // => Logs 'later' after one second.
	     */
	    var delay = baseRest(function(func, wait, args) {
	      return baseDelay(func, toNumber(wait) || 0, args);
	    });
	
	    /**
	     * Creates a function that invokes `func` with arguments reversed.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Function
	     * @param {Function} func The function to flip arguments for.
	     * @returns {Function} Returns the new flipped function.
	     * @example
	     *
	     * var flipped = _.flip(function() {
	     *   return _.toArray(arguments);
	     * });
	     *
	     * flipped('a', 'b', 'c', 'd');
	     * // => ['d', 'c', 'b', 'a']
	     */
	    function flip(func) {
	      return createWrap(func, WRAP_FLIP_FLAG);
	    }
	
	    /**
	     * Creates a function that memoizes the result of `func`. If `resolver` is
	     * provided, it determines the cache key for storing the result based on the
	     * arguments provided to the memoized function. By default, the first argument
	     * provided to the memoized function is used as the map cache key. The `func`
	     * is invoked with the `this` binding of the memoized function.
	     *
	     * **Note:** The cache is exposed as the `cache` property on the memoized
	     * function. Its creation may be customized by replacing the `_.memoize.Cache`
	     * constructor with one whose instances implement the
	     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
	     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to have its output memoized.
	     * @param {Function} [resolver] The function to resolve the cache key.
	     * @returns {Function} Returns the new memoized function.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2 };
	     * var other = { 'c': 3, 'd': 4 };
	     *
	     * var values = _.memoize(_.values);
	     * values(object);
	     * // => [1, 2]
	     *
	     * values(other);
	     * // => [3, 4]
	     *
	     * object.a = 2;
	     * values(object);
	     * // => [1, 2]
	     *
	     * // Modify the result cache.
	     * values.cache.set(object, ['a', 'b']);
	     * values(object);
	     * // => ['a', 'b']
	     *
	     * // Replace `_.memoize.Cache`.
	     * _.memoize.Cache = WeakMap;
	     */
	    function memoize(func, resolver) {
	      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      var memoized = function() {
	        var args = arguments,
	            key = resolver ? resolver.apply(this, args) : args[0],
	            cache = memoized.cache;
	
	        if (cache.has(key)) {
	          return cache.get(key);
	        }
	        var result = func.apply(this, args);
	        memoized.cache = cache.set(key, result) || cache;
	        return result;
	      };
	      memoized.cache = new (memoize.Cache || MapCache);
	      return memoized;
	    }
	
	    // Expose `MapCache`.
	    memoize.Cache = MapCache;
	
	    /**
	     * Creates a function that negates the result of the predicate `func`. The
	     * `func` predicate is invoked with the `this` binding and arguments of the
	     * created function.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} predicate The predicate to negate.
	     * @returns {Function} Returns the new negated function.
	     * @example
	     *
	     * function isEven(n) {
	     *   return n % 2 == 0;
	     * }
	     *
	     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
	     * // => [1, 3, 5]
	     */
	    function negate(predicate) {
	      if (typeof predicate != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      return function() {
	        var args = arguments;
	        switch (args.length) {
	          case 0: return !predicate.call(this);
	          case 1: return !predicate.call(this, args[0]);
	          case 2: return !predicate.call(this, args[0], args[1]);
	          case 3: return !predicate.call(this, args[0], args[1], args[2]);
	        }
	        return !predicate.apply(this, args);
	      };
	    }
	
	    /**
	     * Creates a function that is restricted to invoking `func` once. Repeat calls
	     * to the function return the value of the first invocation. The `func` is
	     * invoked with the `this` binding and arguments of the created function.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new restricted function.
	     * @example
	     *
	     * var initialize = _.once(createApplication);
	     * initialize();
	     * initialize();
	     * // => `createApplication` is invoked once
	     */
	    function once(func) {
	      return before(2, func);
	    }
	
	    /**
	     * Creates a function that invokes `func` with its arguments transformed.
	     *
	     * @static
	     * @since 4.0.0
	     * @memberOf _
	     * @category Function
	     * @param {Function} func The function to wrap.
	     * @param {...(Function|Function[])} [transforms=[_.identity]]
	     *  The argument transforms.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * function doubled(n) {
	     *   return n * 2;
	     * }
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var func = _.overArgs(function(x, y) {
	     *   return [x, y];
	     * }, [square, doubled]);
	     *
	     * func(9, 3);
	     * // => [81, 6]
	     *
	     * func(10, 5);
	     * // => [100, 10]
	     */
	    var overArgs = castRest(function(func, transforms) {
	      transforms = (transforms.length == 1 && isArray(transforms[0]))
	        ? arrayMap(transforms[0], baseUnary(getIteratee()))
	        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
	
	      var funcsLength = transforms.length;
	      return baseRest(function(args) {
	        var index = -1,
	            length = nativeMin(args.length, funcsLength);
	
	        while (++index < length) {
	          args[index] = transforms[index].call(this, args[index]);
	        }
	        return apply(func, this, args);
	      });
	    });
	
	    /**
	     * Creates a function that invokes `func` with `partials` prepended to the
	     * arguments it receives. This method is like `_.bind` except it does **not**
	     * alter the `this` binding.
	     *
	     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for partially applied arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of partially
	     * applied functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.2.0
	     * @category Function
	     * @param {Function} func The function to partially apply arguments to.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new partially applied function.
	     * @example
	     *
	     * function greet(greeting, name) {
	     *   return greeting + ' ' + name;
	     * }
	     *
	     * var sayHelloTo = _.partial(greet, 'hello');
	     * sayHelloTo('fred');
	     * // => 'hello fred'
	     *
	     * // Partially applied with placeholders.
	     * var greetFred = _.partial(greet, _, 'fred');
	     * greetFred('hi');
	     * // => 'hi fred'
	     */
	    var partial = baseRest(function(func, partials) {
	      var holders = replaceHolders(partials, getHolder(partial));
	      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
	    });
	
	    /**
	     * This method is like `_.partial` except that partially applied arguments
	     * are appended to the arguments it receives.
	     *
	     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for partially applied arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of partially
	     * applied functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.0.0
	     * @category Function
	     * @param {Function} func The function to partially apply arguments to.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new partially applied function.
	     * @example
	     *
	     * function greet(greeting, name) {
	     *   return greeting + ' ' + name;
	     * }
	     *
	     * var greetFred = _.partialRight(greet, 'fred');
	     * greetFred('hi');
	     * // => 'hi fred'
	     *
	     * // Partially applied with placeholders.
	     * var sayHelloTo = _.partialRight(greet, 'hello', _);
	     * sayHelloTo('fred');
	     * // => 'hello fred'
	     */
	    var partialRight = baseRest(function(func, partials) {
	      var holders = replaceHolders(partials, getHolder(partialRight));
	      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
	    });
	
	    /**
	     * Creates a function that invokes `func` with arguments arranged according
	     * to the specified `indexes` where the argument value at the first index is
	     * provided as the first argument, the argument value at the second index is
	     * provided as the second argument, and so on.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} func The function to rearrange arguments for.
	     * @param {...(number|number[])} indexes The arranged argument indexes.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var rearged = _.rearg(function(a, b, c) {
	     *   return [a, b, c];
	     * }, [2, 0, 1]);
	     *
	     * rearged('b', 'c', 'a')
	     * // => ['a', 'b', 'c']
	     */
	    var rearg = flatRest(function(func, indexes) {
	      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
	    });
	
	    /**
	     * Creates a function that invokes `func` with the `this` binding of the
	     * created function and arguments from `start` and beyond provided as
	     * an array.
	     *
	     * **Note:** This method is based on the
	     * [rest parameter](https://mdn.io/rest_parameters).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Function
	     * @param {Function} func The function to apply a rest parameter to.
	     * @param {number} [start=func.length-1] The start position of the rest parameter.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var say = _.rest(function(what, names) {
	     *   return what + ' ' + _.initial(names).join(', ') +
	     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
	     * });
	     *
	     * say('hello', 'fred', 'barney', 'pebbles');
	     * // => 'hello fred, barney, & pebbles'
	     */
	    function rest(func, start) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      start = start === undefined ? start : toInteger(start);
	      return baseRest(func, start);
	    }
	
	    /**
	     * Creates a function that invokes `func` with the `this` binding of the
	     * create function and an array of arguments much like
	     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
	     *
	     * **Note:** This method is based on the
	     * [spread operator](https://mdn.io/spread_operator).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.2.0
	     * @category Function
	     * @param {Function} func The function to spread arguments over.
	     * @param {number} [start=0] The start position of the spread.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var say = _.spread(function(who, what) {
	     *   return who + ' says ' + what;
	     * });
	     *
	     * say(['fred', 'hello']);
	     * // => 'fred says hello'
	     *
	     * var numbers = Promise.all([
	     *   Promise.resolve(40),
	     *   Promise.resolve(36)
	     * ]);
	     *
	     * numbers.then(_.spread(function(x, y) {
	     *   return x + y;
	     * }));
	     * // => a Promise of 76
	     */
	    function spread(func, start) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      start = start == null ? 0 : nativeMax(toInteger(start), 0);
	      return baseRest(function(args) {
	        var array = args[start],
	            otherArgs = castSlice(args, 0, start);
	
	        if (array) {
	          arrayPush(otherArgs, array);
	        }
	        return apply(func, this, otherArgs);
	      });
	    }
	
	    /**
	     * Creates a throttled function that only invokes `func` at most once per
	     * every `wait` milliseconds. The throttled function comes with a `cancel`
	     * method to cancel delayed `func` invocations and a `flush` method to
	     * immediately invoke them. Provide `options` to indicate whether `func`
	     * should be invoked on the leading and/or trailing edge of the `wait`
	     * timeout. The `func` is invoked with the last arguments provided to the
	     * throttled function. Subsequent calls to the throttled function return the
	     * result of the last `func` invocation.
	     *
	     * **Note:** If `leading` and `trailing` options are `true`, `func` is
	     * invoked on the trailing edge of the timeout only if the throttled function
	     * is invoked more than once during the `wait` timeout.
	     *
	     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	     *
	     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	     * for details over the differences between `_.throttle` and `_.debounce`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to throttle.
	     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
	     * @param {Object} [options={}] The options object.
	     * @param {boolean} [options.leading=true]
	     *  Specify invoking on the leading edge of the timeout.
	     * @param {boolean} [options.trailing=true]
	     *  Specify invoking on the trailing edge of the timeout.
	     * @returns {Function} Returns the new throttled function.
	     * @example
	     *
	     * // Avoid excessively updating the position while scrolling.
	     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
	     *
	     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
	     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
	     * jQuery(element).on('click', throttled);
	     *
	     * // Cancel the trailing throttled invocation.
	     * jQuery(window).on('popstate', throttled.cancel);
	     */
	    function throttle(func, wait, options) {
	      var leading = true,
	          trailing = true;
	
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      if (isObject(options)) {
	        leading = 'leading' in options ? !!options.leading : leading;
	        trailing = 'trailing' in options ? !!options.trailing : trailing;
	      }
	      return debounce(func, wait, {
	        'leading': leading,
	        'maxWait': wait,
	        'trailing': trailing
	      });
	    }
	
	    /**
	     * Creates a function that accepts up to one argument, ignoring any
	     * additional arguments.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Function
	     * @param {Function} func The function to cap arguments for.
	     * @returns {Function} Returns the new capped function.
	     * @example
	     *
	     * _.map(['6', '8', '10'], _.unary(parseInt));
	     * // => [6, 8, 10]
	     */
	    function unary(func) {
	      return ary(func, 1);
	    }
	
	    /**
	     * Creates a function that provides `value` to `wrapper` as its first
	     * argument. Any additional arguments provided to the function are appended
	     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
	     * binding of the created function.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {*} value The value to wrap.
	     * @param {Function} [wrapper=identity] The wrapper function.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var p = _.wrap(_.escape, function(func, text) {
	     *   return '<p>' + func(text) + '</p>';
	     * });
	     *
	     * p('fred, barney, & pebbles');
	     * // => '<p>fred, barney, &amp; pebbles</p>'
	     */
	    function wrap(value, wrapper) {
	      return partial(castFunction(wrapper), value);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Casts `value` as an array if it's not one.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.4.0
	     * @category Lang
	     * @param {*} value The value to inspect.
	     * @returns {Array} Returns the cast array.
	     * @example
	     *
	     * _.castArray(1);
	     * // => [1]
	     *
	     * _.castArray({ 'a': 1 });
	     * // => [{ 'a': 1 }]
	     *
	     * _.castArray('abc');
	     * // => ['abc']
	     *
	     * _.castArray(null);
	     * // => [null]
	     *
	     * _.castArray(undefined);
	     * // => [undefined]
	     *
	     * _.castArray();
	     * // => []
	     *
	     * var array = [1, 2, 3];
	     * console.log(_.castArray(array) === array);
	     * // => true
	     */
	    function castArray() {
	      if (!arguments.length) {
	        return [];
	      }
	      var value = arguments[0];
	      return isArray(value) ? value : [value];
	    }
	
	    /**
	     * Creates a shallow clone of `value`.
	     *
	     * **Note:** This method is loosely based on the
	     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
	     * and supports cloning arrays, array buffers, booleans, date objects, maps,
	     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
	     * arrays. The own enumerable properties of `arguments` objects are cloned
	     * as plain objects. An empty object is returned for uncloneable values such
	     * as error objects, functions, DOM nodes, and WeakMaps.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to clone.
	     * @returns {*} Returns the cloned value.
	     * @see _.cloneDeep
	     * @example
	     *
	     * var objects = [{ 'a': 1 }, { 'b': 2 }];
	     *
	     * var shallow = _.clone(objects);
	     * console.log(shallow[0] === objects[0]);
	     * // => true
	     */
	    function clone(value) {
	      return baseClone(value, CLONE_SYMBOLS_FLAG);
	    }
	
	    /**
	     * This method is like `_.clone` except that it accepts `customizer` which
	     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
	     * cloning is handled by the method instead. The `customizer` is invoked with
	     * up to four arguments; (value [, index|key, object, stack]).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to clone.
	     * @param {Function} [customizer] The function to customize cloning.
	     * @returns {*} Returns the cloned value.
	     * @see _.cloneDeepWith
	     * @example
	     *
	     * function customizer(value) {
	     *   if (_.isElement(value)) {
	     *     return value.cloneNode(false);
	     *   }
	     * }
	     *
	     * var el = _.cloneWith(document.body, customizer);
	     *
	     * console.log(el === document.body);
	     * // => false
	     * console.log(el.nodeName);
	     * // => 'BODY'
	     * console.log(el.childNodes.length);
	     * // => 0
	     */
	    function cloneWith(value, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
	    }
	
	    /**
	     * This method is like `_.clone` except that it recursively clones `value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.0.0
	     * @category Lang
	     * @param {*} value The value to recursively clone.
	     * @returns {*} Returns the deep cloned value.
	     * @see _.clone
	     * @example
	     *
	     * var objects = [{ 'a': 1 }, { 'b': 2 }];
	     *
	     * var deep = _.cloneDeep(objects);
	     * console.log(deep[0] === objects[0]);
	     * // => false
	     */
	    function cloneDeep(value) {
	      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
	    }
	
	    /**
	     * This method is like `_.cloneWith` except that it recursively clones `value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to recursively clone.
	     * @param {Function} [customizer] The function to customize cloning.
	     * @returns {*} Returns the deep cloned value.
	     * @see _.cloneWith
	     * @example
	     *
	     * function customizer(value) {
	     *   if (_.isElement(value)) {
	     *     return value.cloneNode(true);
	     *   }
	     * }
	     *
	     * var el = _.cloneDeepWith(document.body, customizer);
	     *
	     * console.log(el === document.body);
	     * // => false
	     * console.log(el.nodeName);
	     * // => 'BODY'
	     * console.log(el.childNodes.length);
	     * // => 20
	     */
	    function cloneDeepWith(value, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
	    }
	
	    /**
	     * Checks if `object` conforms to `source` by invoking the predicate
	     * properties of `source` with the corresponding property values of `object`.
	     *
	     * **Note:** This method is equivalent to `_.conforms` when `source` is
	     * partially applied.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.14.0
	     * @category Lang
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2 };
	     *
	     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
	     * // => true
	     *
	     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
	     * // => false
	     */
	    function conformsTo(object, source) {
	      return source == null || baseConformsTo(object, source, keys(source));
	    }
	
	    /**
	     * Performs a
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * comparison between two values to determine if they are equivalent.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	     * @example
	     *
	     * var object = { 'a': 1 };
	     * var other = { 'a': 1 };
	     *
	     * _.eq(object, object);
	     * // => true
	     *
	     * _.eq(object, other);
	     * // => false
	     *
	     * _.eq('a', 'a');
	     * // => true
	     *
	     * _.eq('a', Object('a'));
	     * // => false
	     *
	     * _.eq(NaN, NaN);
	     * // => true
	     */
	    function eq(value, other) {
	      return value === other || (value !== value && other !== other);
	    }
	
	    /**
	     * Checks if `value` is greater than `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is greater than `other`,
	     *  else `false`.
	     * @see _.lt
	     * @example
	     *
	     * _.gt(3, 1);
	     * // => true
	     *
	     * _.gt(3, 3);
	     * // => false
	     *
	     * _.gt(1, 3);
	     * // => false
	     */
	    var gt = createRelationalOperation(baseGt);
	
	    /**
	     * Checks if `value` is greater than or equal to `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is greater than or equal to
	     *  `other`, else `false`.
	     * @see _.lte
	     * @example
	     *
	     * _.gte(3, 1);
	     * // => true
	     *
	     * _.gte(3, 3);
	     * // => true
	     *
	     * _.gte(1, 3);
	     * // => false
	     */
	    var gte = createRelationalOperation(function(value, other) {
	      return value >= other;
	    });
	
	    /**
	     * Checks if `value` is likely an `arguments` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	     *  else `false`.
	     * @example
	     *
	     * _.isArguments(function() { return arguments; }());
	     * // => true
	     *
	     * _.isArguments([1, 2, 3]);
	     * // => false
	     */
	    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
	      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
	        !propertyIsEnumerable.call(value, 'callee');
	    };
	
	    /**
	     * Checks if `value` is classified as an `Array` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an array, else `false`.
	     * @example
	     *
	     * _.isArray([1, 2, 3]);
	     * // => true
	     *
	     * _.isArray(document.body.children);
	     * // => false
	     *
	     * _.isArray('abc');
	     * // => false
	     *
	     * _.isArray(_.noop);
	     * // => false
	     */
	    var isArray = Array.isArray;
	
	    /**
	     * Checks if `value` is classified as an `ArrayBuffer` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
	     * @example
	     *
	     * _.isArrayBuffer(new ArrayBuffer(2));
	     * // => true
	     *
	     * _.isArrayBuffer(new Array(2));
	     * // => false
	     */
	    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
	
	    /**
	     * Checks if `value` is array-like. A value is considered array-like if it's
	     * not a function and has a `value.length` that's an integer greater than or
	     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
	     * @example
	     *
	     * _.isArrayLike([1, 2, 3]);
	     * // => true
	     *
	     * _.isArrayLike(document.body.children);
	     * // => true
	     *
	     * _.isArrayLike('abc');
	     * // => true
	     *
	     * _.isArrayLike(_.noop);
	     * // => false
	     */
	    function isArrayLike(value) {
	      return value != null && isLength(value.length) && !isFunction(value);
	    }
	
	    /**
	     * This method is like `_.isArrayLike` except that it also checks if `value`
	     * is an object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an array-like object,
	     *  else `false`.
	     * @example
	     *
	     * _.isArrayLikeObject([1, 2, 3]);
	     * // => true
	     *
	     * _.isArrayLikeObject(document.body.children);
	     * // => true
	     *
	     * _.isArrayLikeObject('abc');
	     * // => false
	     *
	     * _.isArrayLikeObject(_.noop);
	     * // => false
	     */
	    function isArrayLikeObject(value) {
	      return isObjectLike(value) && isArrayLike(value);
	    }
	
	    /**
	     * Checks if `value` is classified as a boolean primitive or object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
	     * @example
	     *
	     * _.isBoolean(false);
	     * // => true
	     *
	     * _.isBoolean(null);
	     * // => false
	     */
	    function isBoolean(value) {
	      return value === true || value === false ||
	        (isObjectLike(value) && baseGetTag(value) == boolTag);
	    }
	
	    /**
	     * Checks if `value` is a buffer.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
	     * @example
	     *
	     * _.isBuffer(new Buffer(2));
	     * // => true
	     *
	     * _.isBuffer(new Uint8Array(2));
	     * // => false
	     */
	    var isBuffer = nativeIsBuffer || stubFalse;
	
	    /**
	     * Checks if `value` is classified as a `Date` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
	     * @example
	     *
	     * _.isDate(new Date);
	     * // => true
	     *
	     * _.isDate('Mon April 23 2012');
	     * // => false
	     */
	    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
	
	    /**
	     * Checks if `value` is likely a DOM element.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
	     * @example
	     *
	     * _.isElement(document.body);
	     * // => true
	     *
	     * _.isElement('<body>');
	     * // => false
	     */
	    function isElement(value) {
	      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
	    }
	
	    /**
	     * Checks if `value` is an empty object, collection, map, or set.
	     *
	     * Objects are considered empty if they have no own enumerable string keyed
	     * properties.
	     *
	     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
	     * jQuery-like collections are considered empty if they have a `length` of `0`.
	     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
	     * @example
	     *
	     * _.isEmpty(null);
	     * // => true
	     *
	     * _.isEmpty(true);
	     * // => true
	     *
	     * _.isEmpty(1);
	     * // => true
	     *
	     * _.isEmpty([1, 2, 3]);
	     * // => false
	     *
	     * _.isEmpty({ 'a': 1 });
	     * // => false
	     */
	    function isEmpty(value) {
	      if (value == null) {
	        return true;
	      }
	      if (isArrayLike(value) &&
	          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
	            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
	        return !value.length;
	      }
	      var tag = getTag(value);
	      if (tag == mapTag || tag == setTag) {
	        return !value.size;
	      }
	      if (isPrototype(value)) {
	        return !baseKeys(value).length;
	      }
	      for (var key in value) {
	        if (hasOwnProperty.call(value, key)) {
	          return false;
	        }
	      }
	      return true;
	    }
	
	    /**
	     * Performs a deep comparison between two values to determine if they are
	     * equivalent.
	     *
	     * **Note:** This method supports comparing arrays, array buffers, booleans,
	     * date objects, error objects, maps, numbers, `Object` objects, regexes,
	     * sets, strings, symbols, and typed arrays. `Object` objects are compared
	     * by their own, not inherited, enumerable properties. Functions and DOM
	     * nodes are compared by strict equality, i.e. `===`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	     * @example
	     *
	     * var object = { 'a': 1 };
	     * var other = { 'a': 1 };
	     *
	     * _.isEqual(object, other);
	     * // => true
	     *
	     * object === other;
	     * // => false
	     */
	    function isEqual(value, other) {
	      return baseIsEqual(value, other);
	    }
	
	    /**
	     * This method is like `_.isEqual` except that it accepts `customizer` which
	     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
	     * are handled by the method instead. The `customizer` is invoked with up to
	     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	     * @example
	     *
	     * function isGreeting(value) {
	     *   return /^h(?:i|ello)$/.test(value);
	     * }
	     *
	     * function customizer(objValue, othValue) {
	     *   if (isGreeting(objValue) && isGreeting(othValue)) {
	     *     return true;
	     *   }
	     * }
	     *
	     * var array = ['hello', 'goodbye'];
	     * var other = ['hi', 'goodbye'];
	     *
	     * _.isEqualWith(array, other, customizer);
	     * // => true
	     */
	    function isEqualWith(value, other, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      var result = customizer ? customizer(value, other) : undefined;
	      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
	    }
	
	    /**
	     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
	     * `SyntaxError`, `TypeError`, or `URIError` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
	     * @example
	     *
	     * _.isError(new Error);
	     * // => true
	     *
	     * _.isError(Error);
	     * // => false
	     */
	    function isError(value) {
	      if (!isObjectLike(value)) {
	        return false;
	      }
	      var tag = baseGetTag(value);
	      return tag == errorTag || tag == domExcTag ||
	        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
	    }
	
	    /**
	     * Checks if `value` is a finite primitive number.
	     *
	     * **Note:** This method is based on
	     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
	     * @example
	     *
	     * _.isFinite(3);
	     * // => true
	     *
	     * _.isFinite(Number.MIN_VALUE);
	     * // => true
	     *
	     * _.isFinite(Infinity);
	     * // => false
	     *
	     * _.isFinite('3');
	     * // => false
	     */
	    function isFinite(value) {
	      return typeof value == 'number' && nativeIsFinite(value);
	    }
	
	    /**
	     * Checks if `value` is classified as a `Function` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
	     * @example
	     *
	     * _.isFunction(_);
	     * // => true
	     *
	     * _.isFunction(/abc/);
	     * // => false
	     */
	    function isFunction(value) {
	      if (!isObject(value)) {
	        return false;
	      }
	      // The use of `Object#toString` avoids issues with the `typeof` operator
	      // in Safari 9 which returns 'object' for typed arrays and other constructors.
	      var tag = baseGetTag(value);
	      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
	    }
	
	    /**
	     * Checks if `value` is an integer.
	     *
	     * **Note:** This method is based on
	     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
	     * @example
	     *
	     * _.isInteger(3);
	     * // => true
	     *
	     * _.isInteger(Number.MIN_VALUE);
	     * // => false
	     *
	     * _.isInteger(Infinity);
	     * // => false
	     *
	     * _.isInteger('3');
	     * // => false
	     */
	    function isInteger(value) {
	      return typeof value == 'number' && value == toInteger(value);
	    }
	
	    /**
	     * Checks if `value` is a valid array-like length.
	     *
	     * **Note:** This method is loosely based on
	     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
	     * @example
	     *
	     * _.isLength(3);
	     * // => true
	     *
	     * _.isLength(Number.MIN_VALUE);
	     * // => false
	     *
	     * _.isLength(Infinity);
	     * // => false
	     *
	     * _.isLength('3');
	     * // => false
	     */
	    function isLength(value) {
	      return typeof value == 'number' &&
	        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
	    }
	
	    /**
	     * Checks if `value` is the
	     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
	     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
	     * @example
	     *
	     * _.isObject({});
	     * // => true
	     *
	     * _.isObject([1, 2, 3]);
	     * // => true
	     *
	     * _.isObject(_.noop);
	     * // => true
	     *
	     * _.isObject(null);
	     * // => false
	     */
	    function isObject(value) {
	      var type = typeof value;
	      return value != null && (type == 'object' || type == 'function');
	    }
	
	    /**
	     * Checks if `value` is object-like. A value is object-like if it's not `null`
	     * and has a `typeof` result of "object".
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
	     * @example
	     *
	     * _.isObjectLike({});
	     * // => true
	     *
	     * _.isObjectLike([1, 2, 3]);
	     * // => true
	     *
	     * _.isObjectLike(_.noop);
	     * // => false
	     *
	     * _.isObjectLike(null);
	     * // => false
	     */
	    function isObjectLike(value) {
	      return value != null && typeof value == 'object';
	    }
	
	    /**
	     * Checks if `value` is classified as a `Map` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
	     * @example
	     *
	     * _.isMap(new Map);
	     * // => true
	     *
	     * _.isMap(new WeakMap);
	     * // => false
	     */
	    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
	
	    /**
	     * Performs a partial deep comparison between `object` and `source` to
	     * determine if `object` contains equivalent property values.
	     *
	     * **Note:** This method is equivalent to `_.matches` when `source` is
	     * partially applied.
	     *
	     * Partial comparisons will match empty array and empty object `source`
	     * values against any array or object value, respectively. See `_.isEqual`
	     * for a list of supported value comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property values to match.
	     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2 };
	     *
	     * _.isMatch(object, { 'b': 2 });
	     * // => true
	     *
	     * _.isMatch(object, { 'b': 1 });
	     * // => false
	     */
	    function isMatch(object, source) {
	      return object === source || baseIsMatch(object, source, getMatchData(source));
	    }
	
	    /**
	     * This method is like `_.isMatch` except that it accepts `customizer` which
	     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
	     * are handled by the method instead. The `customizer` is invoked with five
	     * arguments: (objValue, srcValue, index|key, object, source).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property values to match.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
	     * @example
	     *
	     * function isGreeting(value) {
	     *   return /^h(?:i|ello)$/.test(value);
	     * }
	     *
	     * function customizer(objValue, srcValue) {
	     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
	     *     return true;
	     *   }
	     * }
	     *
	     * var object = { 'greeting': 'hello' };
	     * var source = { 'greeting': 'hi' };
	     *
	     * _.isMatchWith(object, source, customizer);
	     * // => true
	     */
	    function isMatchWith(object, source, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return baseIsMatch(object, source, getMatchData(source), customizer);
	    }
	
	    /**
	     * Checks if `value` is `NaN`.
	     *
	     * **Note:** This method is based on
	     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
	     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
	     * `undefined` and other non-number values.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
	     * @example
	     *
	     * _.isNaN(NaN);
	     * // => true
	     *
	     * _.isNaN(new Number(NaN));
	     * // => true
	     *
	     * isNaN(undefined);
	     * // => true
	     *
	     * _.isNaN(undefined);
	     * // => false
	     */
	    function isNaN(value) {
	      // An `NaN` primitive is the only value that is not equal to itself.
	      // Perform the `toStringTag` check first to avoid errors with some
	      // ActiveX objects in IE.
	      return isNumber(value) && value != +value;
	    }
	
	    /**
	     * Checks if `value` is a pristine native function.
	     *
	     * **Note:** This method can't reliably detect native functions in the presence
	     * of the core-js package because core-js circumvents this kind of detection.
	     * Despite multiple requests, the core-js maintainer has made it clear: any
	     * attempt to fix the detection will be obstructed. As a result, we're left
	     * with little choice but to throw an error. Unfortunately, this also affects
	     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
	     * which rely on core-js.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a native function,
	     *  else `false`.
	     * @example
	     *
	     * _.isNative(Array.prototype.push);
	     * // => true
	     *
	     * _.isNative(_);
	     * // => false
	     */
	    function isNative(value) {
	      if (isMaskable(value)) {
	        throw new Error(CORE_ERROR_TEXT);
	      }
	      return baseIsNative(value);
	    }
	
	    /**
	     * Checks if `value` is `null`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
	     * @example
	     *
	     * _.isNull(null);
	     * // => true
	     *
	     * _.isNull(void 0);
	     * // => false
	     */
	    function isNull(value) {
	      return value === null;
	    }
	
	    /**
	     * Checks if `value` is `null` or `undefined`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
	     * @example
	     *
	     * _.isNil(null);
	     * // => true
	     *
	     * _.isNil(void 0);
	     * // => true
	     *
	     * _.isNil(NaN);
	     * // => false
	     */
	    function isNil(value) {
	      return value == null;
	    }
	
	    /**
	     * Checks if `value` is classified as a `Number` primitive or object.
	     *
	     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
	     * classified as numbers, use the `_.isFinite` method.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
	     * @example
	     *
	     * _.isNumber(3);
	     * // => true
	     *
	     * _.isNumber(Number.MIN_VALUE);
	     * // => true
	     *
	     * _.isNumber(Infinity);
	     * // => true
	     *
	     * _.isNumber('3');
	     * // => false
	     */
	    function isNumber(value) {
	      return typeof value == 'number' ||
	        (isObjectLike(value) && baseGetTag(value) == numberTag);
	    }
	
	    /**
	     * Checks if `value` is a plain object, that is, an object created by the
	     * `Object` constructor or one with a `[[Prototype]]` of `null`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.8.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     * }
	     *
	     * _.isPlainObject(new Foo);
	     * // => false
	     *
	     * _.isPlainObject([1, 2, 3]);
	     * // => false
	     *
	     * _.isPlainObject({ 'x': 0, 'y': 0 });
	     * // => true
	     *
	     * _.isPlainObject(Object.create(null));
	     * // => true
	     */
	    function isPlainObject(value) {
	      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
	        return false;
	      }
	      var proto = getPrototype(value);
	      if (proto === null) {
	        return true;
	      }
	      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
	      return typeof Ctor == 'function' && Ctor instanceof Ctor &&
	        funcToString.call(Ctor) == objectCtorString;
	    }
	
	    /**
	     * Checks if `value` is classified as a `RegExp` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
	     * @example
	     *
	     * _.isRegExp(/abc/);
	     * // => true
	     *
	     * _.isRegExp('/abc/');
	     * // => false
	     */
	    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
	
	    /**
	     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
	     * double precision number which isn't the result of a rounded unsafe integer.
	     *
	     * **Note:** This method is based on
	     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
	     * @example
	     *
	     * _.isSafeInteger(3);
	     * // => true
	     *
	     * _.isSafeInteger(Number.MIN_VALUE);
	     * // => false
	     *
	     * _.isSafeInteger(Infinity);
	     * // => false
	     *
	     * _.isSafeInteger('3');
	     * // => false
	     */
	    function isSafeInteger(value) {
	      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
	    }
	
	    /**
	     * Checks if `value` is classified as a `Set` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
	     * @example
	     *
	     * _.isSet(new Set);
	     * // => true
	     *
	     * _.isSet(new WeakSet);
	     * // => false
	     */
	    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
	
	    /**
	     * Checks if `value` is classified as a `String` primitive or object.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
	     * @example
	     *
	     * _.isString('abc');
	     * // => true
	     *
	     * _.isString(1);
	     * // => false
	     */
	    function isString(value) {
	      return typeof value == 'string' ||
	        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
	    }
	
	    /**
	     * Checks if `value` is classified as a `Symbol` primitive or object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
	     * @example
	     *
	     * _.isSymbol(Symbol.iterator);
	     * // => true
	     *
	     * _.isSymbol('abc');
	     * // => false
	     */
	    function isSymbol(value) {
	      return typeof value == 'symbol' ||
	        (isObjectLike(value) && baseGetTag(value) == symbolTag);
	    }
	
	    /**
	     * Checks if `value` is classified as a typed array.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	     * @example
	     *
	     * _.isTypedArray(new Uint8Array);
	     * // => true
	     *
	     * _.isTypedArray([]);
	     * // => false
	     */
	    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
	
	    /**
	     * Checks if `value` is `undefined`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
	     * @example
	     *
	     * _.isUndefined(void 0);
	     * // => true
	     *
	     * _.isUndefined(null);
	     * // => false
	     */
	    function isUndefined(value) {
	      return value === undefined;
	    }
	
	    /**
	     * Checks if `value` is classified as a `WeakMap` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
	     * @example
	     *
	     * _.isWeakMap(new WeakMap);
	     * // => true
	     *
	     * _.isWeakMap(new Map);
	     * // => false
	     */
	    function isWeakMap(value) {
	      return isObjectLike(value) && getTag(value) == weakMapTag;
	    }
	
	    /**
	     * Checks if `value` is classified as a `WeakSet` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
	     * @example
	     *
	     * _.isWeakSet(new WeakSet);
	     * // => true
	     *
	     * _.isWeakSet(new Set);
	     * // => false
	     */
	    function isWeakSet(value) {
	      return isObjectLike(value) && baseGetTag(value) == weakSetTag;
	    }
	
	    /**
	     * Checks if `value` is less than `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is less than `other`,
	     *  else `false`.
	     * @see _.gt
	     * @example
	     *
	     * _.lt(1, 3);
	     * // => true
	     *
	     * _.lt(3, 3);
	     * // => false
	     *
	     * _.lt(3, 1);
	     * // => false
	     */
	    var lt = createRelationalOperation(baseLt);
	
	    /**
	     * Checks if `value` is less than or equal to `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is less than or equal to
	     *  `other`, else `false`.
	     * @see _.gte
	     * @example
	     *
	     * _.lte(1, 3);
	     * // => true
	     *
	     * _.lte(3, 3);
	     * // => true
	     *
	     * _.lte(3, 1);
	     * // => false
	     */
	    var lte = createRelationalOperation(function(value, other) {
	      return value <= other;
	    });
	
	    /**
	     * Converts `value` to an array.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {Array} Returns the converted array.
	     * @example
	     *
	     * _.toArray({ 'a': 1, 'b': 2 });
	     * // => [1, 2]
	     *
	     * _.toArray('abc');
	     * // => ['a', 'b', 'c']
	     *
	     * _.toArray(1);
	     * // => []
	     *
	     * _.toArray(null);
	     * // => []
	     */
	    function toArray(value) {
	      if (!value) {
	        return [];
	      }
	      if (isArrayLike(value)) {
	        return isString(value) ? stringToArray(value) : copyArray(value);
	      }
	      if (symIterator && value[symIterator]) {
	        return iteratorToArray(value[symIterator]());
	      }
	      var tag = getTag(value),
	          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
	
	      return func(value);
	    }
	
	    /**
	     * Converts `value` to a finite number.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.12.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted number.
	     * @example
	     *
	     * _.toFinite(3.2);
	     * // => 3.2
	     *
	     * _.toFinite(Number.MIN_VALUE);
	     * // => 5e-324
	     *
	     * _.toFinite(Infinity);
	     * // => 1.7976931348623157e+308
	     *
	     * _.toFinite('3.2');
	     * // => 3.2
	     */
	    function toFinite(value) {
	      if (!value) {
	        return value === 0 ? value : 0;
	      }
	      value = toNumber(value);
	      if (value === INFINITY || value === -INFINITY) {
	        var sign = (value < 0 ? -1 : 1);
	        return sign * MAX_INTEGER;
	      }
	      return value === value ? value : 0;
	    }
	
	    /**
	     * Converts `value` to an integer.
	     *
	     * **Note:** This method is loosely based on
	     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.toInteger(3.2);
	     * // => 3
	     *
	     * _.toInteger(Number.MIN_VALUE);
	     * // => 0
	     *
	     * _.toInteger(Infinity);
	     * // => 1.7976931348623157e+308
	     *
	     * _.toInteger('3.2');
	     * // => 3
	     */
	    function toInteger(value) {
	      var result = toFinite(value),
	          remainder = result % 1;
	
	      return result === result ? (remainder ? result - remainder : result) : 0;
	    }
	
	    /**
	     * Converts `value` to an integer suitable for use as the length of an
	     * array-like object.
	     *
	     * **Note:** This method is based on
	     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.toLength(3.2);
	     * // => 3
	     *
	     * _.toLength(Number.MIN_VALUE);
	     * // => 0
	     *
	     * _.toLength(Infinity);
	     * // => 4294967295
	     *
	     * _.toLength('3.2');
	     * // => 3
	     */
	    function toLength(value) {
	      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
	    }
	
	    /**
	     * Converts `value` to a number.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to process.
	     * @returns {number} Returns the number.
	     * @example
	     *
	     * _.toNumber(3.2);
	     * // => 3.2
	     *
	     * _.toNumber(Number.MIN_VALUE);
	     * // => 5e-324
	     *
	     * _.toNumber(Infinity);
	     * // => Infinity
	     *
	     * _.toNumber('3.2');
	     * // => 3.2
	     */
	    function toNumber(value) {
	      if (typeof value == 'number') {
	        return value;
	      }
	      if (isSymbol(value)) {
	        return NAN;
	      }
	      if (isObject(value)) {
	        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
	        value = isObject(other) ? (other + '') : other;
	      }
	      if (typeof value != 'string') {
	        return value === 0 ? value : +value;
	      }
	      value = value.replace(reTrim, '');
	      var isBinary = reIsBinary.test(value);
	      return (isBinary || reIsOctal.test(value))
	        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
	        : (reIsBadHex.test(value) ? NAN : +value);
	    }
	
	    /**
	     * Converts `value` to a plain object flattening inherited enumerable string
	     * keyed properties of `value` to own properties of the plain object.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {Object} Returns the converted plain object.
	     * @example
	     *
	     * function Foo() {
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.assign({ 'a': 1 }, new Foo);
	     * // => { 'a': 1, 'b': 2 }
	     *
	     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
	     * // => { 'a': 1, 'b': 2, 'c': 3 }
	     */
	    function toPlainObject(value) {
	      return copyObject(value, keysIn(value));
	    }
	
	    /**
	     * Converts `value` to a safe integer. A safe integer can be compared and
	     * represented correctly.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.toSafeInteger(3.2);
	     * // => 3
	     *
	     * _.toSafeInteger(Number.MIN_VALUE);
	     * // => 0
	     *
	     * _.toSafeInteger(Infinity);
	     * // => 9007199254740991
	     *
	     * _.toSafeInteger('3.2');
	     * // => 3
	     */
	    function toSafeInteger(value) {
	      return value
	        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
	        : (value === 0 ? value : 0);
	    }
	
	    /**
	     * Converts `value` to a string. An empty string is returned for `null`
	     * and `undefined` values. The sign of `-0` is preserved.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {string} Returns the converted string.
	     * @example
	     *
	     * _.toString(null);
	     * // => ''
	     *
	     * _.toString(-0);
	     * // => '-0'
	     *
	     * _.toString([1, 2, 3]);
	     * // => '1,2,3'
	     */
	    function toString(value) {
	      return value == null ? '' : baseToString(value);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Assigns own enumerable string keyed properties of source objects to the
	     * destination object. Source objects are applied from left to right.
	     * Subsequent sources overwrite property assignments of previous sources.
	     *
	     * **Note:** This method mutates `object` and is loosely based on
	     * [`Object.assign`](https://mdn.io/Object/assign).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.10.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.assignIn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     * }
	     *
	     * function Bar() {
	     *   this.c = 3;
	     * }
	     *
	     * Foo.prototype.b = 2;
	     * Bar.prototype.d = 4;
	     *
	     * _.assign({ 'a': 0 }, new Foo, new Bar);
	     * // => { 'a': 1, 'c': 3 }
	     */
	    var assign = createAssigner(function(object, source) {
	      if (isPrototype(source) || isArrayLike(source)) {
	        copyObject(source, keys(source), object);
	        return;
	      }
	      for (var key in source) {
	        if (hasOwnProperty.call(source, key)) {
	          assignValue(object, key, source[key]);
	        }
	      }
	    });
	
	    /**
	     * This method is like `_.assign` except that it iterates over own and
	     * inherited source properties.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias extend
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.assign
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     * }
	     *
	     * function Bar() {
	     *   this.c = 3;
	     * }
	     *
	     * Foo.prototype.b = 2;
	     * Bar.prototype.d = 4;
	     *
	     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
	     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
	     */
	    var assignIn = createAssigner(function(object, source) {
	      copyObject(source, keysIn(source), object);
	    });
	
	    /**
	     * This method is like `_.assignIn` except that it accepts `customizer`
	     * which is invoked to produce the assigned values. If `customizer` returns
	     * `undefined`, assignment is handled by the method instead. The `customizer`
	     * is invoked with five arguments: (objValue, srcValue, key, object, source).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias extendWith
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} sources The source objects.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @see _.assignWith
	     * @example
	     *
	     * function customizer(objValue, srcValue) {
	     *   return _.isUndefined(objValue) ? srcValue : objValue;
	     * }
	     *
	     * var defaults = _.partialRight(_.assignInWith, customizer);
	     *
	     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
	     * // => { 'a': 1, 'b': 2 }
	     */
	    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
	      copyObject(source, keysIn(source), object, customizer);
	    });
	
	    /**
	     * This method is like `_.assign` except that it accepts `customizer`
	     * which is invoked to produce the assigned values. If `customizer` returns
	     * `undefined`, assignment is handled by the method instead. The `customizer`
	     * is invoked with five arguments: (objValue, srcValue, key, object, source).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} sources The source objects.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @see _.assignInWith
	     * @example
	     *
	     * function customizer(objValue, srcValue) {
	     *   return _.isUndefined(objValue) ? srcValue : objValue;
	     * }
	     *
	     * var defaults = _.partialRight(_.assignWith, customizer);
	     *
	     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
	     * // => { 'a': 1, 'b': 2 }
	     */
	    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
	      copyObject(source, keys(source), object, customizer);
	    });
	
	    /**
	     * Creates an array of values corresponding to `paths` of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.0.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {...(string|string[])} [paths] The property paths to pick.
	     * @returns {Array} Returns the picked values.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
	     *
	     * _.at(object, ['a[0].b.c', 'a[1]']);
	     * // => [3, 4]
	     */
	    var at = flatRest(baseAt);
	
	    /**
	     * Creates an object that inherits from the `prototype` object. If a
	     * `properties` object is given, its own enumerable string keyed properties
	     * are assigned to the created object.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.3.0
	     * @category Object
	     * @param {Object} prototype The object to inherit from.
	     * @param {Object} [properties] The properties to assign to the object.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * function Shape() {
	     *   this.x = 0;
	     *   this.y = 0;
	     * }
	     *
	     * function Circle() {
	     *   Shape.call(this);
	     * }
	     *
	     * Circle.prototype = _.create(Shape.prototype, {
	     *   'constructor': Circle
	     * });
	     *
	     * var circle = new Circle;
	     * circle instanceof Circle;
	     * // => true
	     *
	     * circle instanceof Shape;
	     * // => true
	     */
	    function create(prototype, properties) {
	      var result = baseCreate(prototype);
	      return properties == null ? result : baseAssign(result, properties);
	    }
	
	    /**
	     * Assigns own and inherited enumerable string keyed properties of source
	     * objects to the destination object for all destination properties that
	     * resolve to `undefined`. Source objects are applied from left to right.
	     * Once a property is set, additional values of the same property are ignored.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.defaultsDeep
	     * @example
	     *
	     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
	     * // => { 'a': 1, 'b': 2 }
	     */
	    var defaults = baseRest(function(args) {
	      args.push(undefined, customDefaultsAssignIn);
	      return apply(assignInWith, undefined, args);
	    });
	
	    /**
	     * This method is like `_.defaults` except that it recursively assigns
	     * default properties.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.defaults
	     * @example
	     *
	     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
	     * // => { 'a': { 'b': 2, 'c': 3 } }
	     */
	    var defaultsDeep = baseRest(function(args) {
	      args.push(undefined, customDefaultsMerge);
	      return apply(mergeWith, undefined, args);
	    });
	
	    /**
	     * This method is like `_.find` except that it returns the key of the first
	     * element `predicate` returns truthy for instead of the element itself.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.1.0
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {string|undefined} Returns the key of the matched element,
	     *  else `undefined`.
	     * @example
	     *
	     * var users = {
	     *   'barney':  { 'age': 36, 'active': true },
	     *   'fred':    { 'age': 40, 'active': false },
	     *   'pebbles': { 'age': 1,  'active': true }
	     * };
	     *
	     * _.findKey(users, function(o) { return o.age < 40; });
	     * // => 'barney' (iteration order is not guaranteed)
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findKey(users, { 'age': 1, 'active': true });
	     * // => 'pebbles'
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findKey(users, ['active', false]);
	     * // => 'fred'
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findKey(users, 'active');
	     * // => 'barney'
	     */
	    function findKey(object, predicate) {
	      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
	    }
	
	    /**
	     * This method is like `_.findKey` except that it iterates over elements of
	     * a collection in the opposite order.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {string|undefined} Returns the key of the matched element,
	     *  else `undefined`.
	     * @example
	     *
	     * var users = {
	     *   'barney':  { 'age': 36, 'active': true },
	     *   'fred':    { 'age': 40, 'active': false },
	     *   'pebbles': { 'age': 1,  'active': true }
	     * };
	     *
	     * _.findLastKey(users, function(o) { return o.age < 40; });
	     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findLastKey(users, { 'age': 36, 'active': true });
	     * // => 'barney'
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findLastKey(users, ['active', false]);
	     * // => 'fred'
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findLastKey(users, 'active');
	     * // => 'pebbles'
	     */
	    function findLastKey(object, predicate) {
	      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
	    }
	
	    /**
	     * Iterates over own and inherited enumerable string keyed properties of an
	     * object and invokes `iteratee` for each property. The iteratee is invoked
	     * with three arguments: (value, key, object). Iteratee functions may exit
	     * iteration early by explicitly returning `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.3.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forInRight
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forIn(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
	     */
	    function forIn(object, iteratee) {
	      return object == null
	        ? object
	        : baseFor(object, getIteratee(iteratee, 3), keysIn);
	    }
	
	    /**
	     * This method is like `_.forIn` except that it iterates over properties of
	     * `object` in the opposite order.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forIn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forInRight(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
	     */
	    function forInRight(object, iteratee) {
	      return object == null
	        ? object
	        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
	    }
	
	    /**
	     * Iterates over own enumerable string keyed properties of an object and
	     * invokes `iteratee` for each property. The iteratee is invoked with three
	     * arguments: (value, key, object). Iteratee functions may exit iteration
	     * early by explicitly returning `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.3.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forOwnRight
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forOwn(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
	     */
	    function forOwn(object, iteratee) {
	      return object && baseForOwn(object, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * This method is like `_.forOwn` except that it iterates over properties of
	     * `object` in the opposite order.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forOwn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forOwnRight(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
	     */
	    function forOwnRight(object, iteratee) {
	      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * Creates an array of function property names from own enumerable properties
	     * of `object`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @returns {Array} Returns the function names.
	     * @see _.functionsIn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = _.constant('a');
	     *   this.b = _.constant('b');
	     * }
	     *
	     * Foo.prototype.c = _.constant('c');
	     *
	     * _.functions(new Foo);
	     * // => ['a', 'b']
	     */
	    function functions(object) {
	      return object == null ? [] : baseFunctions(object, keys(object));
	    }
	
	    /**
	     * Creates an array of function property names from own and inherited
	     * enumerable properties of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @returns {Array} Returns the function names.
	     * @see _.functions
	     * @example
	     *
	     * function Foo() {
	     *   this.a = _.constant('a');
	     *   this.b = _.constant('b');
	     * }
	     *
	     * Foo.prototype.c = _.constant('c');
	     *
	     * _.functionsIn(new Foo);
	     * // => ['a', 'b', 'c']
	     */
	    function functionsIn(object) {
	      return object == null ? [] : baseFunctions(object, keysIn(object));
	    }
	
	    /**
	     * Gets the value at `path` of `object`. If the resolved value is
	     * `undefined`, the `defaultValue` is returned in its place.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.7.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the property to get.
	     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
	     * @returns {*} Returns the resolved value.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
	     *
	     * _.get(object, 'a[0].b.c');
	     * // => 3
	     *
	     * _.get(object, ['a', '0', 'b', 'c']);
	     * // => 3
	     *
	     * _.get(object, 'a.b.c', 'default');
	     * // => 'default'
	     */
	    function get(object, path, defaultValue) {
	      var result = object == null ? undefined : baseGet(object, path);
	      return result === undefined ? defaultValue : result;
	    }
	
	    /**
	     * Checks if `path` is a direct property of `object`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path to check.
	     * @returns {boolean} Returns `true` if `path` exists, else `false`.
	     * @example
	     *
	     * var object = { 'a': { 'b': 2 } };
	     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
	     *
	     * _.has(object, 'a');
	     * // => true
	     *
	     * _.has(object, 'a.b');
	     * // => true
	     *
	     * _.has(object, ['a', 'b']);
	     * // => true
	     *
	     * _.has(other, 'a');
	     * // => false
	     */
	    function has(object, path) {
	      return object != null && hasPath(object, path, baseHas);
	    }
	
	    /**
	     * Checks if `path` is a direct or inherited property of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path to check.
	     * @returns {boolean} Returns `true` if `path` exists, else `false`.
	     * @example
	     *
	     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
	     *
	     * _.hasIn(object, 'a');
	     * // => true
	     *
	     * _.hasIn(object, 'a.b');
	     * // => true
	     *
	     * _.hasIn(object, ['a', 'b']);
	     * // => true
	     *
	     * _.hasIn(object, 'b');
	     * // => false
	     */
	    function hasIn(object, path) {
	      return object != null && hasPath(object, path, baseHasIn);
	    }
	
	    /**
	     * Creates an object composed of the inverted keys and values of `object`.
	     * If `object` contains duplicate values, subsequent values overwrite
	     * property assignments of previous values.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.7.0
	     * @category Object
	     * @param {Object} object The object to invert.
	     * @returns {Object} Returns the new inverted object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2, 'c': 1 };
	     *
	     * _.invert(object);
	     * // => { '1': 'c', '2': 'b' }
	     */
	    var invert = createInverter(function(result, value, key) {
	      result[value] = key;
	    }, constant(identity));
	
	    /**
	     * This method is like `_.invert` except that the inverted object is generated
	     * from the results of running each element of `object` thru `iteratee`. The
	     * corresponding inverted value of each inverted key is an array of keys
	     * responsible for generating the inverted value. The iteratee is invoked
	     * with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.1.0
	     * @category Object
	     * @param {Object} object The object to invert.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Object} Returns the new inverted object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2, 'c': 1 };
	     *
	     * _.invertBy(object);
	     * // => { '1': ['a', 'c'], '2': ['b'] }
	     *
	     * _.invertBy(object, function(value) {
	     *   return 'group' + value;
	     * });
	     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
	     */
	    var invertBy = createInverter(function(result, value, key) {
	      if (hasOwnProperty.call(result, value)) {
	        result[value].push(key);
	      } else {
	        result[value] = [key];
	      }
	    }, getIteratee);
	
	    /**
	     * Invokes the method at `path` of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the method to invoke.
	     * @param {...*} [args] The arguments to invoke the method with.
	     * @returns {*} Returns the result of the invoked method.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
	     *
	     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
	     * // => [2, 3]
	     */
	    var invoke = baseRest(baseInvoke);
	
	    /**
	     * Creates an array of the own enumerable property names of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects. See the
	     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
	     * for more details.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.keys(new Foo);
	     * // => ['a', 'b'] (iteration order is not guaranteed)
	     *
	     * _.keys('hi');
	     * // => ['0', '1']
	     */
	    function keys(object) {
	      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
	    }
	
	    /**
	     * Creates an array of the own and inherited enumerable property names of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.keysIn(new Foo);
	     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
	     */
	    function keysIn(object) {
	      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
	    }
	
	    /**
	     * The opposite of `_.mapValues`; this method creates an object with the
	     * same values as `object` and keys generated by running each own enumerable
	     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
	     * with three arguments: (value, key, object).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.8.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns the new mapped object.
	     * @see _.mapValues
	     * @example
	     *
	     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
	     *   return key + value;
	     * });
	     * // => { 'a1': 1, 'b2': 2 }
	     */
	    function mapKeys(object, iteratee) {
	      var result = {};
	      iteratee = getIteratee(iteratee, 3);
	
	      baseForOwn(object, function(value, key, object) {
	        baseAssignValue(result, iteratee(value, key, object), value);
	      });
	      return result;
	    }
	
	    /**
	     * Creates an object with the same keys as `object` and values generated
	     * by running each own enumerable string keyed property of `object` thru
	     * `iteratee`. The iteratee is invoked with three arguments:
	     * (value, key, object).
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns the new mapped object.
	     * @see _.mapKeys
	     * @example
	     *
	     * var users = {
	     *   'fred':    { 'user': 'fred',    'age': 40 },
	     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
	     * };
	     *
	     * _.mapValues(users, function(o) { return o.age; });
	     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.mapValues(users, 'age');
	     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
	     */
	    function mapValues(object, iteratee) {
	      var result = {};
	      iteratee = getIteratee(iteratee, 3);
	
	      baseForOwn(object, function(value, key, object) {
	        baseAssignValue(result, key, iteratee(value, key, object));
	      });
	      return result;
	    }
	
	    /**
	     * This method is like `_.assign` except that it recursively merges own and
	     * inherited enumerable string keyed properties of source objects into the
	     * destination object. Source properties that resolve to `undefined` are
	     * skipped if a destination value exists. Array and plain object properties
	     * are merged recursively. Other objects and value types are overridden by
	     * assignment. Source objects are applied from left to right. Subsequent
	     * sources overwrite property assignments of previous sources.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.5.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = {
	     *   'a': [{ 'b': 2 }, { 'd': 4 }]
	     * };
	     *
	     * var other = {
	     *   'a': [{ 'c': 3 }, { 'e': 5 }]
	     * };
	     *
	     * _.merge(object, other);
	     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
	     */
	    var merge = createAssigner(function(object, source, srcIndex) {
	      baseMerge(object, source, srcIndex);
	    });
	
	    /**
	     * This method is like `_.merge` except that it accepts `customizer` which
	     * is invoked to produce the merged values of the destination and source
	     * properties. If `customizer` returns `undefined`, merging is handled by the
	     * method instead. The `customizer` is invoked with six arguments:
	     * (objValue, srcValue, key, object, source, stack).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} sources The source objects.
	     * @param {Function} customizer The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * function customizer(objValue, srcValue) {
	     *   if (_.isArray(objValue)) {
	     *     return objValue.concat(srcValue);
	     *   }
	     * }
	     *
	     * var object = { 'a': [1], 'b': [2] };
	     * var other = { 'a': [3], 'b': [4] };
	     *
	     * _.mergeWith(object, other, customizer);
	     * // => { 'a': [1, 3], 'b': [2, 4] }
	     */
	    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
	      baseMerge(object, source, srcIndex, customizer);
	    });
	
	    /**
	     * The opposite of `_.pick`; this method creates an object composed of the
	     * own and inherited enumerable property paths of `object` that are not omitted.
	     *
	     * **Note:** This method is considerably slower than `_.pick`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {...(string|string[])} [paths] The property paths to omit.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.omit(object, ['a', 'c']);
	     * // => { 'b': '2' }
	     */
	    var omit = flatRest(function(object, paths) {
	      var result = {};
	      if (object == null) {
	        return result;
	      }
	      var isDeep = false;
	      paths = arrayMap(paths, function(path) {
	        path = castPath(path, object);
	        isDeep || (isDeep = path.length > 1);
	        return path;
	      });
	      copyObject(object, getAllKeysIn(object), result);
	      if (isDeep) {
	        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
	      }
	      var length = paths.length;
	      while (length--) {
	        baseUnset(result, paths[length]);
	      }
	      return result;
	    });
	
	    /**
	     * The opposite of `_.pickBy`; this method creates an object composed of
	     * the own and inherited enumerable string keyed properties of `object` that
	     * `predicate` doesn't return truthy for. The predicate is invoked with two
	     * arguments: (value, key).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {Function} [predicate=_.identity] The function invoked per property.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.omitBy(object, _.isNumber);
	     * // => { 'b': '2' }
	     */
	    function omitBy(object, predicate) {
	      return pickBy(object, negate(getIteratee(predicate)));
	    }
	
	    /**
	     * Creates an object composed of the picked `object` properties.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {...(string|string[])} [paths] The property paths to pick.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.pick(object, ['a', 'c']);
	     * // => { 'a': 1, 'c': 3 }
	     */
	    var pick = flatRest(function(object, paths) {
	      return object == null ? {} : basePick(object, paths);
	    });
	
	    /**
	     * Creates an object composed of the `object` properties `predicate` returns
	     * truthy for. The predicate is invoked with two arguments: (value, key).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {Function} [predicate=_.identity] The function invoked per property.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.pickBy(object, _.isNumber);
	     * // => { 'a': 1, 'c': 3 }
	     */
	    function pickBy(object, predicate) {
	      if (object == null) {
	        return {};
	      }
	      var props = arrayMap(getAllKeysIn(object), function(prop) {
	        return [prop];
	      });
	      predicate = getIteratee(predicate);
	      return basePickBy(object, props, function(value, path) {
	        return predicate(value, path[0]);
	      });
	    }
	
	    /**
	     * This method is like `_.get` except that if the resolved value is a
	     * function it's invoked with the `this` binding of its parent object and
	     * its result is returned.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the property to resolve.
	     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
	     * @returns {*} Returns the resolved value.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
	     *
	     * _.result(object, 'a[0].b.c1');
	     * // => 3
	     *
	     * _.result(object, 'a[0].b.c2');
	     * // => 4
	     *
	     * _.result(object, 'a[0].b.c3', 'default');
	     * // => 'default'
	     *
	     * _.result(object, 'a[0].b.c3', _.constant('default'));
	     * // => 'default'
	     */
	    function result(object, path, defaultValue) {
	      path = castPath(path, object);
	
	      var index = -1,
	          length = path.length;
	
	      // Ensure the loop is entered when path is empty.
	      if (!length) {
	        length = 1;
	        object = undefined;
	      }
	      while (++index < length) {
	        var value = object == null ? undefined : object[toKey(path[index])];
	        if (value === undefined) {
	          index = length;
	          value = defaultValue;
	        }
	        object = isFunction(value) ? value.call(object) : value;
	      }
	      return object;
	    }
	
	    /**
	     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
	     * it's created. Arrays are created for missing index properties while objects
	     * are created for all other missing properties. Use `_.setWith` to customize
	     * `path` creation.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.7.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {*} value The value to set.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
	     *
	     * _.set(object, 'a[0].b.c', 4);
	     * console.log(object.a[0].b.c);
	     * // => 4
	     *
	     * _.set(object, ['x', '0', 'y', 'z'], 5);
	     * console.log(object.x[0].y.z);
	     * // => 5
	     */
	    function set(object, path, value) {
	      return object == null ? object : baseSet(object, path, value);
	    }
	
	    /**
	     * This method is like `_.set` except that it accepts `customizer` which is
	     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
	     * path creation is handled by the method instead. The `customizer` is invoked
	     * with three arguments: (nsValue, key, nsObject).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {*} value The value to set.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = {};
	     *
	     * _.setWith(object, '[0][1]', 'a', Object);
	     * // => { '0': { '1': 'a' } }
	     */
	    function setWith(object, path, value, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return object == null ? object : baseSet(object, path, value, customizer);
	    }
	
	    /**
	     * Creates an array of own enumerable string keyed-value pairs for `object`
	     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
	     * entries are returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias entries
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the key-value pairs.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.toPairs(new Foo);
	     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
	     */
	    var toPairs = createToPairs(keys);
	
	    /**
	     * Creates an array of own and inherited enumerable string keyed-value pairs
	     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
	     * or set, its entries are returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias entriesIn
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the key-value pairs.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.toPairsIn(new Foo);
	     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
	     */
	    var toPairsIn = createToPairs(keysIn);
	
	    /**
	     * An alternative to `_.reduce`; this method transforms `object` to a new
	     * `accumulator` object which is the result of running each of its own
	     * enumerable string keyed properties thru `iteratee`, with each invocation
	     * potentially mutating the `accumulator` object. If `accumulator` is not
	     * provided, a new object with the same `[[Prototype]]` will be used. The
	     * iteratee is invoked with four arguments: (accumulator, value, key, object).
	     * Iteratee functions may exit iteration early by explicitly returning `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.3.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @param {*} [accumulator] The custom accumulator value.
	     * @returns {*} Returns the accumulated value.
	     * @example
	     *
	     * _.transform([2, 3, 4], function(result, n) {
	     *   result.push(n *= n);
	     *   return n % 2 == 0;
	     * }, []);
	     * // => [4, 9]
	     *
	     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
	     *   (result[value] || (result[value] = [])).push(key);
	     * }, {});
	     * // => { '1': ['a', 'c'], '2': ['b'] }
	     */
	    function transform(object, iteratee, accumulator) {
	      var isArr = isArray(object),
	          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
	
	      iteratee = getIteratee(iteratee, 4);
	      if (accumulator == null) {
	        var Ctor = object && object.constructor;
	        if (isArrLike) {
	          accumulator = isArr ? new Ctor : [];
	        }
	        else if (isObject(object)) {
	          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
	        }
	        else {
	          accumulator = {};
	        }
	      }
	      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
	        return iteratee(accumulator, value, index, object);
	      });
	      return accumulator;
	    }
	
	    /**
	     * Removes the property at `path` of `object`.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to unset.
	     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
	     * _.unset(object, 'a[0].b.c');
	     * // => true
	     *
	     * console.log(object);
	     * // => { 'a': [{ 'b': {} }] };
	     *
	     * _.unset(object, ['a', '0', 'b', 'c']);
	     * // => true
	     *
	     * console.log(object);
	     * // => { 'a': [{ 'b': {} }] };
	     */
	    function unset(object, path) {
	      return object == null ? true : baseUnset(object, path);
	    }
	
	    /**
	     * This method is like `_.set` except that accepts `updater` to produce the
	     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
	     * is invoked with one argument: (value).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.6.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {Function} updater The function to produce the updated value.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
	     *
	     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
	     * console.log(object.a[0].b.c);
	     * // => 9
	     *
	     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
	     * console.log(object.x[0].y.z);
	     * // => 0
	     */
	    function update(object, path, updater) {
	      return object == null ? object : baseUpdate(object, path, castFunction(updater));
	    }
	
	    /**
	     * This method is like `_.update` except that it accepts `customizer` which is
	     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
	     * path creation is handled by the method instead. The `customizer` is invoked
	     * with three arguments: (nsValue, key, nsObject).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.6.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {Function} updater The function to produce the updated value.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = {};
	     *
	     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
	     * // => { '0': { '1': 'a' } }
	     */
	    function updateWith(object, path, updater, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
	    }
	
	    /**
	     * Creates an array of the own enumerable string keyed property values of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property values.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.values(new Foo);
	     * // => [1, 2] (iteration order is not guaranteed)
	     *
	     * _.values('hi');
	     * // => ['h', 'i']
	     */
	    function values(object) {
	      return object == null ? [] : baseValues(object, keys(object));
	    }
	
	    /**
	     * Creates an array of the own and inherited enumerable string keyed property
	     * values of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property values.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.valuesIn(new Foo);
	     * // => [1, 2, 3] (iteration order is not guaranteed)
	     */
	    function valuesIn(object) {
	      return object == null ? [] : baseValues(object, keysIn(object));
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Clamps `number` within the inclusive `lower` and `upper` bounds.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Number
	     * @param {number} number The number to clamp.
	     * @param {number} [lower] The lower bound.
	     * @param {number} upper The upper bound.
	     * @returns {number} Returns the clamped number.
	     * @example
	     *
	     * _.clamp(-10, -5, 5);
	     * // => -5
	     *
	     * _.clamp(10, -5, 5);
	     * // => 5
	     */
	    function clamp(number, lower, upper) {
	      if (upper === undefined) {
	        upper = lower;
	        lower = undefined;
	      }
	      if (upper !== undefined) {
	        upper = toNumber(upper);
	        upper = upper === upper ? upper : 0;
	      }
	      if (lower !== undefined) {
	        lower = toNumber(lower);
	        lower = lower === lower ? lower : 0;
	      }
	      return baseClamp(toNumber(number), lower, upper);
	    }
	
	    /**
	     * Checks if `n` is between `start` and up to, but not including, `end`. If
	     * `end` is not specified, it's set to `start` with `start` then set to `0`.
	     * If `start` is greater than `end` the params are swapped to support
	     * negative ranges.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.3.0
	     * @category Number
	     * @param {number} number The number to check.
	     * @param {number} [start=0] The start of the range.
	     * @param {number} end The end of the range.
	     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
	     * @see _.range, _.rangeRight
	     * @example
	     *
	     * _.inRange(3, 2, 4);
	     * // => true
	     *
	     * _.inRange(4, 8);
	     * // => true
	     *
	     * _.inRange(4, 2);
	     * // => false
	     *
	     * _.inRange(2, 2);
	     * // => false
	     *
	     * _.inRange(1.2, 2);
	     * // => true
	     *
	     * _.inRange(5.2, 4);
	     * // => false
	     *
	     * _.inRange(-3, -2, -6);
	     * // => true
	     */
	    function inRange(number, start, end) {
	      start = toFinite(start);
	      if (end === undefined) {
	        end = start;
	        start = 0;
	      } else {
	        end = toFinite(end);
	      }
	      number = toNumber(number);
	      return baseInRange(number, start, end);
	    }
	
	    /**
	     * Produces a random number between the inclusive `lower` and `upper` bounds.
	     * If only one argument is provided a number between `0` and the given number
	     * is returned. If `floating` is `true`, or either `lower` or `upper` are
	     * floats, a floating-point number is returned instead of an integer.
	     *
	     * **Note:** JavaScript follows the IEEE-754 standard for resolving
	     * floating-point values which can produce unexpected results.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.7.0
	     * @category Number
	     * @param {number} [lower=0] The lower bound.
	     * @param {number} [upper=1] The upper bound.
	     * @param {boolean} [floating] Specify returning a floating-point number.
	     * @returns {number} Returns the random number.
	     * @example
	     *
	     * _.random(0, 5);
	     * // => an integer between 0 and 5
	     *
	     * _.random(5);
	     * // => also an integer between 0 and 5
	     *
	     * _.random(5, true);
	     * // => a floating-point number between 0 and 5
	     *
	     * _.random(1.2, 5.2);
	     * // => a floating-point number between 1.2 and 5.2
	     */
	    function random(lower, upper, floating) {
	      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
	        upper = floating = undefined;
	      }
	      if (floating === undefined) {
	        if (typeof upper == 'boolean') {
	          floating = upper;
	          upper = undefined;
	        }
	        else if (typeof lower == 'boolean') {
	          floating = lower;
	          lower = undefined;
	        }
	      }
	      if (lower === undefined && upper === undefined) {
	        lower = 0;
	        upper = 1;
	      }
	      else {
	        lower = toFinite(lower);
	        if (upper === undefined) {
	          upper = lower;
	          lower = 0;
	        } else {
	          upper = toFinite(upper);
	        }
	      }
	      if (lower > upper) {
	        var temp = lower;
	        lower = upper;
	        upper = temp;
	      }
	      if (floating || lower % 1 || upper % 1) {
	        var rand = nativeRandom();
	        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
	      }
	      return baseRandom(lower, upper);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the camel cased string.
	     * @example
	     *
	     * _.camelCase('Foo Bar');
	     * // => 'fooBar'
	     *
	     * _.camelCase('--foo-bar--');
	     * // => 'fooBar'
	     *
	     * _.camelCase('__FOO_BAR__');
	     * // => 'fooBar'
	     */
	    var camelCase = createCompounder(function(result, word, index) {
	      word = word.toLowerCase();
	      return result + (index ? capitalize(word) : word);
	    });
	
	    /**
	     * Converts the first character of `string` to upper case and the remaining
	     * to lower case.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to capitalize.
	     * @returns {string} Returns the capitalized string.
	     * @example
	     *
	     * _.capitalize('FRED');
	     * // => 'Fred'
	     */
	    function capitalize(string) {
	      return upperFirst(toString(string).toLowerCase());
	    }
	
	    /**
	     * Deburrs `string` by converting
	     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
	     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
	     * letters to basic Latin letters and removing
	     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to deburr.
	     * @returns {string} Returns the deburred string.
	     * @example
	     *
	     * _.deburr('déjà vu');
	     * // => 'deja vu'
	     */
	    function deburr(string) {
	      string = toString(string);
	      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
	    }
	
	    /**
	     * Checks if `string` ends with the given target string.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to inspect.
	     * @param {string} [target] The string to search for.
	     * @param {number} [position=string.length] The position to search up to.
	     * @returns {boolean} Returns `true` if `string` ends with `target`,
	     *  else `false`.
	     * @example
	     *
	     * _.endsWith('abc', 'c');
	     * // => true
	     *
	     * _.endsWith('abc', 'b');
	     * // => false
	     *
	     * _.endsWith('abc', 'b', 2);
	     * // => true
	     */
	    function endsWith(string, target, position) {
	      string = toString(string);
	      target = baseToString(target);
	
	      var length = string.length;
	      position = position === undefined
	        ? length
	        : baseClamp(toInteger(position), 0, length);
	
	      var end = position;
	      position -= target.length;
	      return position >= 0 && string.slice(position, end) == target;
	    }
	
	    /**
	     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
	     * corresponding HTML entities.
	     *
	     * **Note:** No other characters are escaped. To escape additional
	     * characters use a third-party library like [_he_](https://mths.be/he).
	     *
	     * Though the ">" character is escaped for symmetry, characters like
	     * ">" and "/" don't need escaping in HTML and have no special meaning
	     * unless they're part of a tag or unquoted attribute value. See
	     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
	     * (under "semi-related fun fact") for more details.
	     *
	     * When working with HTML you should always
	     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
	     * XSS vectors.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category String
	     * @param {string} [string=''] The string to escape.
	     * @returns {string} Returns the escaped string.
	     * @example
	     *
	     * _.escape('fred, barney, & pebbles');
	     * // => 'fred, barney, &amp; pebbles'
	     */
	    function escape(string) {
	      string = toString(string);
	      return (string && reHasUnescapedHtml.test(string))
	        ? string.replace(reUnescapedHtml, escapeHtmlChar)
	        : string;
	    }
	
	    /**
	     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
	     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to escape.
	     * @returns {string} Returns the escaped string.
	     * @example
	     *
	     * _.escapeRegExp('[lodash](https://lodash.com/)');
	     * // => '\[lodash\]\(https://lodash\.com/\)'
	     */
	    function escapeRegExp(string) {
	      string = toString(string);
	      return (string && reHasRegExpChar.test(string))
	        ? string.replace(reRegExpChar, '\\$&')
	        : string;
	    }
	
	    /**
	     * Converts `string` to
	     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the kebab cased string.
	     * @example
	     *
	     * _.kebabCase('Foo Bar');
	     * // => 'foo-bar'
	     *
	     * _.kebabCase('fooBar');
	     * // => 'foo-bar'
	     *
	     * _.kebabCase('__FOO_BAR__');
	     * // => 'foo-bar'
	     */
	    var kebabCase = createCompounder(function(result, word, index) {
	      return result + (index ? '-' : '') + word.toLowerCase();
	    });
	
	    /**
	     * Converts `string`, as space separated words, to lower case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the lower cased string.
	     * @example
	     *
	     * _.lowerCase('--Foo-Bar--');
	     * // => 'foo bar'
	     *
	     * _.lowerCase('fooBar');
	     * // => 'foo bar'
	     *
	     * _.lowerCase('__FOO_BAR__');
	     * // => 'foo bar'
	     */
	    var lowerCase = createCompounder(function(result, word, index) {
	      return result + (index ? ' ' : '') + word.toLowerCase();
	    });
	
	    /**
	     * Converts the first character of `string` to lower case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the converted string.
	     * @example
	     *
	     * _.lowerFirst('Fred');
	     * // => 'fred'
	     *
	     * _.lowerFirst('FRED');
	     * // => 'fRED'
	     */
	    var lowerFirst = createCaseFirst('toLowerCase');
	
	    /**
	     * Pads `string` on the left and right sides if it's shorter than `length`.
	     * Padding characters are truncated if they can't be evenly divided by `length`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to pad.
	     * @param {number} [length=0] The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padded string.
	     * @example
	     *
	     * _.pad('abc', 8);
	     * // => '  abc   '
	     *
	     * _.pad('abc', 8, '_-');
	     * // => '_-abc_-_'
	     *
	     * _.pad('abc', 3);
	     * // => 'abc'
	     */
	    function pad(string, length, chars) {
	      string = toString(string);
	      length = toInteger(length);
	
	      var strLength = length ? stringSize(string) : 0;
	      if (!length || strLength >= length) {
	        return string;
	      }
	      var mid = (length - strLength) / 2;
	      return (
	        createPadding(nativeFloor(mid), chars) +
	        string +
	        createPadding(nativeCeil(mid), chars)
	      );
	    }
	
	    /**
	     * Pads `string` on the right side if it's shorter than `length`. Padding
	     * characters are truncated if they exceed `length`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to pad.
	     * @param {number} [length=0] The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padded string.
	     * @example
	     *
	     * _.padEnd('abc', 6);
	     * // => 'abc   '
	     *
	     * _.padEnd('abc', 6, '_-');
	     * // => 'abc_-_'
	     *
	     * _.padEnd('abc', 3);
	     * // => 'abc'
	     */
	    function padEnd(string, length, chars) {
	      string = toString(string);
	      length = toInteger(length);
	
	      var strLength = length ? stringSize(string) : 0;
	      return (length && strLength < length)
	        ? (string + createPadding(length - strLength, chars))
	        : string;
	    }
	
	    /**
	     * Pads `string` on the left side if it's shorter than `length`. Padding
	     * characters are truncated if they exceed `length`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to pad.
	     * @param {number} [length=0] The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padded string.
	     * @example
	     *
	     * _.padStart('abc', 6);
	     * // => '   abc'
	     *
	     * _.padStart('abc', 6, '_-');
	     * // => '_-_abc'
	     *
	     * _.padStart('abc', 3);
	     * // => 'abc'
	     */
	    function padStart(string, length, chars) {
	      string = toString(string);
	      length = toInteger(length);
	
	      var strLength = length ? stringSize(string) : 0;
	      return (length && strLength < length)
	        ? (createPadding(length - strLength, chars) + string)
	        : string;
	    }
	
	    /**
	     * Converts `string` to an integer of the specified radix. If `radix` is
	     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
	     * hexadecimal, in which case a `radix` of `16` is used.
	     *
	     * **Note:** This method aligns with the
	     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.1.0
	     * @category String
	     * @param {string} string The string to convert.
	     * @param {number} [radix=10] The radix to interpret `value` by.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.parseInt('08');
	     * // => 8
	     *
	     * _.map(['6', '08', '10'], _.parseInt);
	     * // => [6, 8, 10]
	     */
	    function parseInt(string, radix, guard) {
	      if (guard || radix == null) {
	        radix = 0;
	      } else if (radix) {
	        radix = +radix;
	      }
	      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
	    }
	
	    /**
	     * Repeats the given string `n` times.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to repeat.
	     * @param {number} [n=1] The number of times to repeat the string.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the repeated string.
	     * @example
	     *
	     * _.repeat('*', 3);
	     * // => '***'
	     *
	     * _.repeat('abc', 2);
	     * // => 'abcabc'
	     *
	     * _.repeat('abc', 0);
	     * // => ''
	     */
	    function repeat(string, n, guard) {
	      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
	        n = 1;
	      } else {
	        n = toInteger(n);
	      }
	      return baseRepeat(toString(string), n);
	    }
	
	    /**
	     * Replaces matches for `pattern` in `string` with `replacement`.
	     *
	     * **Note:** This method is based on
	     * [`String#replace`](https://mdn.io/String/replace).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to modify.
	     * @param {RegExp|string} pattern The pattern to replace.
	     * @param {Function|string} replacement The match replacement.
	     * @returns {string} Returns the modified string.
	     * @example
	     *
	     * _.replace('Hi Fred', 'Fred', 'Barney');
	     * // => 'Hi Barney'
	     */
	    function replace() {
	      var args = arguments,
	          string = toString(args[0]);
	
	      return args.length < 3 ? string : string.replace(args[1], args[2]);
	    }
	
	    /**
	     * Converts `string` to
	     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the snake cased string.
	     * @example
	     *
	     * _.snakeCase('Foo Bar');
	     * // => 'foo_bar'
	     *
	     * _.snakeCase('fooBar');
	     * // => 'foo_bar'
	     *
	     * _.snakeCase('--FOO-BAR--');
	     * // => 'foo_bar'
	     */
	    var snakeCase = createCompounder(function(result, word, index) {
	      return result + (index ? '_' : '') + word.toLowerCase();
	    });
	
	    /**
	     * Splits `string` by `separator`.
	     *
	     * **Note:** This method is based on
	     * [`String#split`](https://mdn.io/String/split).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to split.
	     * @param {RegExp|string} separator The separator pattern to split by.
	     * @param {number} [limit] The length to truncate results to.
	     * @returns {Array} Returns the string segments.
	     * @example
	     *
	     * _.split('a-b-c', '-', 2);
	     * // => ['a', 'b']
	     */
	    function split(string, separator, limit) {
	      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
	        separator = limit = undefined;
	      }
	      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
	      if (!limit) {
	        return [];
	      }
	      string = toString(string);
	      if (string && (
	            typeof separator == 'string' ||
	            (separator != null && !isRegExp(separator))
	          )) {
	        separator = baseToString(separator);
	        if (!separator && hasUnicode(string)) {
	          return castSlice(stringToArray(string), 0, limit);
	        }
	      }
	      return string.split(separator, limit);
	    }
	
	    /**
	     * Converts `string` to
	     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.1.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the start cased string.
	     * @example
	     *
	     * _.startCase('--foo-bar--');
	     * // => 'Foo Bar'
	     *
	     * _.startCase('fooBar');
	     * // => 'Foo Bar'
	     *
	     * _.startCase('__FOO_BAR__');
	     * // => 'FOO BAR'
	     */
	    var startCase = createCompounder(function(result, word, index) {
	      return result + (index ? ' ' : '') + upperFirst(word);
	    });
	
	    /**
	     * Checks if `string` starts with the given target string.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to inspect.
	     * @param {string} [target] The string to search for.
	     * @param {number} [position=0] The position to search from.
	     * @returns {boolean} Returns `true` if `string` starts with `target`,
	     *  else `false`.
	     * @example
	     *
	     * _.startsWith('abc', 'a');
	     * // => true
	     *
	     * _.startsWith('abc', 'b');
	     * // => false
	     *
	     * _.startsWith('abc', 'b', 1);
	     * // => true
	     */
	    function startsWith(string, target, position) {
	      string = toString(string);
	      position = position == null
	        ? 0
	        : baseClamp(toInteger(position), 0, string.length);
	
	      target = baseToString(target);
	      return string.slice(position, position + target.length) == target;
	    }
	
	    /**
	     * Creates a compiled template function that can interpolate data properties
	     * in "interpolate" delimiters, HTML-escape interpolated data properties in
	     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
	     * properties may be accessed as free variables in the template. If a setting
	     * object is given, it takes precedence over `_.templateSettings` values.
	     *
	     * **Note:** In the development build `_.template` utilizes
	     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
	     * for easier debugging.
	     *
	     * For more information on precompiling templates see
	     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
	     *
	     * For more information on Chrome extension sandboxes see
	     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category String
	     * @param {string} [string=''] The template string.
	     * @param {Object} [options={}] The options object.
	     * @param {RegExp} [options.escape=_.templateSettings.escape]
	     *  The HTML "escape" delimiter.
	     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
	     *  The "evaluate" delimiter.
	     * @param {Object} [options.imports=_.templateSettings.imports]
	     *  An object to import into the template as free variables.
	     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
	     *  The "interpolate" delimiter.
	     * @param {string} [options.sourceURL='lodash.templateSources[n]']
	     *  The sourceURL of the compiled template.
	     * @param {string} [options.variable='obj']
	     *  The data object variable name.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the compiled template function.
	     * @example
	     *
	     * // Use the "interpolate" delimiter to create a compiled template.
	     * var compiled = _.template('hello <%= user %>!');
	     * compiled({ 'user': 'fred' });
	     * // => 'hello fred!'
	     *
	     * // Use the HTML "escape" delimiter to escape data property values.
	     * var compiled = _.template('<b><%- value %></b>');
	     * compiled({ 'value': '<script>' });
	     * // => '<b>&lt;script&gt;</b>'
	     *
	     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
	     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
	     * compiled({ 'users': ['fred', 'barney'] });
	     * // => '<li>fred</li><li>barney</li>'
	     *
	     * // Use the internal `print` function in "evaluate" delimiters.
	     * var compiled = _.template('<% print("hello " + user); %>!');
	     * compiled({ 'user': 'barney' });
	     * // => 'hello barney!'
	     *
	     * // Use the ES template literal delimiter as an "interpolate" delimiter.
	     * // Disable support by replacing the "interpolate" delimiter.
	     * var compiled = _.template('hello ${ user }!');
	     * compiled({ 'user': 'pebbles' });
	     * // => 'hello pebbles!'
	     *
	     * // Use backslashes to treat delimiters as plain text.
	     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
	     * compiled({ 'value': 'ignored' });
	     * // => '<%- value %>'
	     *
	     * // Use the `imports` option to import `jQuery` as `jq`.
	     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
	     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
	     * compiled({ 'users': ['fred', 'barney'] });
	     * // => '<li>fred</li><li>barney</li>'
	     *
	     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
	     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
	     * compiled(data);
	     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
	     *
	     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
	     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
	     * compiled.source;
	     * // => function(data) {
	     * //   var __t, __p = '';
	     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
	     * //   return __p;
	     * // }
	     *
	     * // Use custom template delimiters.
	     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
	     * var compiled = _.template('hello {{ user }}!');
	     * compiled({ 'user': 'mustache' });
	     * // => 'hello mustache!'
	     *
	     * // Use the `source` property to inline compiled templates for meaningful
	     * // line numbers in error messages and stack traces.
	     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
	     *   var JST = {\
	     *     "main": ' + _.template(mainText).source + '\
	     *   };\
	     * ');
	     */
	    function template(string, options, guard) {
	      // Based on John Resig's `tmpl` implementation
	      // (http://ejohn.org/blog/javascript-micro-templating/)
	      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
	      var settings = lodash.templateSettings;
	
	      if (guard && isIterateeCall(string, options, guard)) {
	        options = undefined;
	      }
	      string = toString(string);
	      options = assignInWith({}, options, settings, customDefaultsAssignIn);
	
	      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
	          importsKeys = keys(imports),
	          importsValues = baseValues(imports, importsKeys);
	
	      var isEscaping,
	          isEvaluating,
	          index = 0,
	          interpolate = options.interpolate || reNoMatch,
	          source = "__p += '";
	
	      // Compile the regexp to match each delimiter.
	      var reDelimiters = RegExp(
	        (options.escape || reNoMatch).source + '|' +
	        interpolate.source + '|' +
	        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
	        (options.evaluate || reNoMatch).source + '|$'
	      , 'g');
	
	      // Use a sourceURL for easier debugging.
	      var sourceURL = '//# sourceURL=' +
	        ('sourceURL' in options
	          ? options.sourceURL
	          : ('lodash.templateSources[' + (++templateCounter) + ']')
	        ) + '\n';
	
	      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
	        interpolateValue || (interpolateValue = esTemplateValue);
	
	        // Escape characters that can't be included in string literals.
	        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
	
	        // Replace delimiters with snippets.
	        if (escapeValue) {
	          isEscaping = true;
	          source += "' +\n__e(" + escapeValue + ") +\n'";
	        }
	        if (evaluateValue) {
	          isEvaluating = true;
	          source += "';\n" + evaluateValue + ";\n__p += '";
	        }
	        if (interpolateValue) {
	          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
	        }
	        index = offset + match.length;
	
	        // The JS engine embedded in Adobe products needs `match` returned in
	        // order to produce the correct `offset` value.
	        return match;
	      });
	
	      source += "';\n";
	
	      // If `variable` is not specified wrap a with-statement around the generated
	      // code to add the data object to the top of the scope chain.
	      var variable = options.variable;
	      if (!variable) {
	        source = 'with (obj) {\n' + source + '\n}\n';
	      }
	      // Cleanup code by stripping empty strings.
	      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
	        .replace(reEmptyStringMiddle, '$1')
	        .replace(reEmptyStringTrailing, '$1;');
	
	      // Frame code as the function body.
	      source = 'function(' + (variable || 'obj') + ') {\n' +
	        (variable
	          ? ''
	          : 'obj || (obj = {});\n'
	        ) +
	        "var __t, __p = ''" +
	        (isEscaping
	           ? ', __e = _.escape'
	           : ''
	        ) +
	        (isEvaluating
	          ? ', __j = Array.prototype.join;\n' +
	            "function print() { __p += __j.call(arguments, '') }\n"
	          : ';\n'
	        ) +
	        source +
	        'return __p\n}';
	
	      var result = attempt(function() {
	        return Function(importsKeys, sourceURL + 'return ' + source)
	          .apply(undefined, importsValues);
	      });
	
	      // Provide the compiled function's source by its `toString` method or
	      // the `source` property as a convenience for inlining compiled templates.
	      result.source = source;
	      if (isError(result)) {
	        throw result;
	      }
	      return result;
	    }
	
	    /**
	     * Converts `string`, as a whole, to lower case just like
	     * [String#toLowerCase](https://mdn.io/toLowerCase).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the lower cased string.
	     * @example
	     *
	     * _.toLower('--Foo-Bar--');
	     * // => '--foo-bar--'
	     *
	     * _.toLower('fooBar');
	     * // => 'foobar'
	     *
	     * _.toLower('__FOO_BAR__');
	     * // => '__foo_bar__'
	     */
	    function toLower(value) {
	      return toString(value).toLowerCase();
	    }
	
	    /**
	     * Converts `string`, as a whole, to upper case just like
	     * [String#toUpperCase](https://mdn.io/toUpperCase).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the upper cased string.
	     * @example
	     *
	     * _.toUpper('--foo-bar--');
	     * // => '--FOO-BAR--'
	     *
	     * _.toUpper('fooBar');
	     * // => 'FOOBAR'
	     *
	     * _.toUpper('__foo_bar__');
	     * // => '__FOO_BAR__'
	     */
	    function toUpper(value) {
	      return toString(value).toUpperCase();
	    }
	
	    /**
	     * Removes leading and trailing whitespace or specified characters from `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to trim.
	     * @param {string} [chars=whitespace] The characters to trim.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the trimmed string.
	     * @example
	     *
	     * _.trim('  abc  ');
	     * // => 'abc'
	     *
	     * _.trim('-_-abc-_-', '_-');
	     * // => 'abc'
	     *
	     * _.map(['  foo  ', '  bar  '], _.trim);
	     * // => ['foo', 'bar']
	     */
	    function trim(string, chars, guard) {
	      string = toString(string);
	      if (string && (guard || chars === undefined)) {
	        return string.replace(reTrim, '');
	      }
	      if (!string || !(chars = baseToString(chars))) {
	        return string;
	      }
	      var strSymbols = stringToArray(string),
	          chrSymbols = stringToArray(chars),
	          start = charsStartIndex(strSymbols, chrSymbols),
	          end = charsEndIndex(strSymbols, chrSymbols) + 1;
	
	      return castSlice(strSymbols, start, end).join('');
	    }
	
	    /**
	     * Removes trailing whitespace or specified characters from `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to trim.
	     * @param {string} [chars=whitespace] The characters to trim.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the trimmed string.
	     * @example
	     *
	     * _.trimEnd('  abc  ');
	     * // => '  abc'
	     *
	     * _.trimEnd('-_-abc-_-', '_-');
	     * // => '-_-abc'
	     */
	    function trimEnd(string, chars, guard) {
	      string = toString(string);
	      if (string && (guard || chars === undefined)) {
	        return string.replace(reTrimEnd, '');
	      }
	      if (!string || !(chars = baseToString(chars))) {
	        return string;
	      }
	      var strSymbols = stringToArray(string),
	          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
	
	      return castSlice(strSymbols, 0, end).join('');
	    }
	
	    /**
	     * Removes leading whitespace or specified characters from `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to trim.
	     * @param {string} [chars=whitespace] The characters to trim.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the trimmed string.
	     * @example
	     *
	     * _.trimStart('  abc  ');
	     * // => 'abc  '
	     *
	     * _.trimStart('-_-abc-_-', '_-');
	     * // => 'abc-_-'
	     */
	    function trimStart(string, chars, guard) {
	      string = toString(string);
	      if (string && (guard || chars === undefined)) {
	        return string.replace(reTrimStart, '');
	      }
	      if (!string || !(chars = baseToString(chars))) {
	        return string;
	      }
	      var strSymbols = stringToArray(string),
	          start = charsStartIndex(strSymbols, stringToArray(chars));
	
	      return castSlice(strSymbols, start).join('');
	    }
	
	    /**
	     * Truncates `string` if it's longer than the given maximum string length.
	     * The last characters of the truncated string are replaced with the omission
	     * string which defaults to "...".
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to truncate.
	     * @param {Object} [options={}] The options object.
	     * @param {number} [options.length=30] The maximum string length.
	     * @param {string} [options.omission='...'] The string to indicate text is omitted.
	     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
	     * @returns {string} Returns the truncated string.
	     * @example
	     *
	     * _.truncate('hi-diddly-ho there, neighborino');
	     * // => 'hi-diddly-ho there, neighbo...'
	     *
	     * _.truncate('hi-diddly-ho there, neighborino', {
	     *   'length': 24,
	     *   'separator': ' '
	     * });
	     * // => 'hi-diddly-ho there,...'
	     *
	     * _.truncate('hi-diddly-ho there, neighborino', {
	     *   'length': 24,
	     *   'separator': /,? +/
	     * });
	     * // => 'hi-diddly-ho there...'
	     *
	     * _.truncate('hi-diddly-ho there, neighborino', {
	     *   'omission': ' [...]'
	     * });
	     * // => 'hi-diddly-ho there, neig [...]'
	     */
	    function truncate(string, options) {
	      var length = DEFAULT_TRUNC_LENGTH,
	          omission = DEFAULT_TRUNC_OMISSION;
	
	      if (isObject(options)) {
	        var separator = 'separator' in options ? options.separator : separator;
	        length = 'length' in options ? toInteger(options.length) : length;
	        omission = 'omission' in options ? baseToString(options.omission) : omission;
	      }
	      string = toString(string);
	
	      var strLength = string.length;
	      if (hasUnicode(string)) {
	        var strSymbols = stringToArray(string);
	        strLength = strSymbols.length;
	      }
	      if (length >= strLength) {
	        return string;
	      }
	      var end = length - stringSize(omission);
	      if (end < 1) {
	        return omission;
	      }
	      var result = strSymbols
	        ? castSlice(strSymbols, 0, end).join('')
	        : string.slice(0, end);
	
	      if (separator === undefined) {
	        return result + omission;
	      }
	      if (strSymbols) {
	        end += (result.length - end);
	      }
	      if (isRegExp(separator)) {
	        if (string.slice(end).search(separator)) {
	          var match,
	              substring = result;
	
	          if (!separator.global) {
	            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
	          }
	          separator.lastIndex = 0;
	          while ((match = separator.exec(substring))) {
	            var newEnd = match.index;
	          }
	          result = result.slice(0, newEnd === undefined ? end : newEnd);
	        }
	      } else if (string.indexOf(baseToString(separator), end) != end) {
	        var index = result.lastIndexOf(separator);
	        if (index > -1) {
	          result = result.slice(0, index);
	        }
	      }
	      return result + omission;
	    }
	
	    /**
	     * The inverse of `_.escape`; this method converts the HTML entities
	     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
	     * their corresponding characters.
	     *
	     * **Note:** No other HTML entities are unescaped. To unescape additional
	     * HTML entities use a third-party library like [_he_](https://mths.be/he).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.6.0
	     * @category String
	     * @param {string} [string=''] The string to unescape.
	     * @returns {string} Returns the unescaped string.
	     * @example
	     *
	     * _.unescape('fred, barney, &amp; pebbles');
	     * // => 'fred, barney, & pebbles'
	     */
	    function unescape(string) {
	      string = toString(string);
	      return (string && reHasEscapedHtml.test(string))
	        ? string.replace(reEscapedHtml, unescapeHtmlChar)
	        : string;
	    }
	
	    /**
	     * Converts `string`, as space separated words, to upper case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the upper cased string.
	     * @example
	     *
	     * _.upperCase('--foo-bar');
	     * // => 'FOO BAR'
	     *
	     * _.upperCase('fooBar');
	     * // => 'FOO BAR'
	     *
	     * _.upperCase('__foo_bar__');
	     * // => 'FOO BAR'
	     */
	    var upperCase = createCompounder(function(result, word, index) {
	      return result + (index ? ' ' : '') + word.toUpperCase();
	    });
	
	    /**
	     * Converts the first character of `string` to upper case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the converted string.
	     * @example
	     *
	     * _.upperFirst('fred');
	     * // => 'Fred'
	     *
	     * _.upperFirst('FRED');
	     * // => 'FRED'
	     */
	    var upperFirst = createCaseFirst('toUpperCase');
	
	    /**
	     * Splits `string` into an array of its words.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to inspect.
	     * @param {RegExp|string} [pattern] The pattern to match words.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the words of `string`.
	     * @example
	     *
	     * _.words('fred, barney, & pebbles');
	     * // => ['fred', 'barney', 'pebbles']
	     *
	     * _.words('fred, barney, & pebbles', /[^, ]+/g);
	     * // => ['fred', 'barney', '&', 'pebbles']
	     */
	    function words(string, pattern, guard) {
	      string = toString(string);
	      pattern = guard ? undefined : pattern;
	
	      if (pattern === undefined) {
	        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
	      }
	      return string.match(pattern) || [];
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Attempts to invoke `func`, returning either the result or the caught error
	     * object. Any additional arguments are provided to `func` when it's invoked.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {Function} func The function to attempt.
	     * @param {...*} [args] The arguments to invoke `func` with.
	     * @returns {*} Returns the `func` result or error object.
	     * @example
	     *
	     * // Avoid throwing errors for invalid selectors.
	     * var elements = _.attempt(function(selector) {
	     *   return document.querySelectorAll(selector);
	     * }, '>_>');
	     *
	     * if (_.isError(elements)) {
	     *   elements = [];
	     * }
	     */
	    var attempt = baseRest(function(func, args) {
	      try {
	        return apply(func, undefined, args);
	      } catch (e) {
	        return isError(e) ? e : new Error(e);
	      }
	    });
	
	    /**
	     * Binds methods of an object to the object itself, overwriting the existing
	     * method.
	     *
	     * **Note:** This method doesn't set the "length" property of bound functions.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {Object} object The object to bind and assign the bound methods to.
	     * @param {...(string|string[])} methodNames The object method names to bind.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var view = {
	     *   'label': 'docs',
	     *   'click': function() {
	     *     console.log('clicked ' + this.label);
	     *   }
	     * };
	     *
	     * _.bindAll(view, ['click']);
	     * jQuery(element).on('click', view.click);
	     * // => Logs 'clicked docs' when clicked.
	     */
	    var bindAll = flatRest(function(object, methodNames) {
	      arrayEach(methodNames, function(key) {
	        key = toKey(key);
	        baseAssignValue(object, key, bind(object[key], object));
	      });
	      return object;
	    });
	
	    /**
	     * Creates a function that iterates over `pairs` and invokes the corresponding
	     * function of the first predicate to return truthy. The predicate-function
	     * pairs are invoked with the `this` binding and arguments of the created
	     * function.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {Array} pairs The predicate-function pairs.
	     * @returns {Function} Returns the new composite function.
	     * @example
	     *
	     * var func = _.cond([
	     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
	     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
	     *   [_.stubTrue,                      _.constant('no match')]
	     * ]);
	     *
	     * func({ 'a': 1, 'b': 2 });
	     * // => 'matches A'
	     *
	     * func({ 'a': 0, 'b': 1 });
	     * // => 'matches B'
	     *
	     * func({ 'a': '1', 'b': '2' });
	     * // => 'no match'
	     */
	    function cond(pairs) {
	      var length = pairs == null ? 0 : pairs.length,
	          toIteratee = getIteratee();
	
	      pairs = !length ? [] : arrayMap(pairs, function(pair) {
	        if (typeof pair[1] != 'function') {
	          throw new TypeError(FUNC_ERROR_TEXT);
	        }
	        return [toIteratee(pair[0]), pair[1]];
	      });
	
	      return baseRest(function(args) {
	        var index = -1;
	        while (++index < length) {
	          var pair = pairs[index];
	          if (apply(pair[0], this, args)) {
	            return apply(pair[1], this, args);
	          }
	        }
	      });
	    }
	
	    /**
	     * Creates a function that invokes the predicate properties of `source` with
	     * the corresponding property values of a given object, returning `true` if
	     * all predicates return truthy, else `false`.
	     *
	     * **Note:** The created function is equivalent to `_.conformsTo` with
	     * `source` partially applied.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {Function} Returns the new spec function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': 2, 'b': 1 },
	     *   { 'a': 1, 'b': 2 }
	     * ];
	     *
	     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
	     * // => [{ 'a': 1, 'b': 2 }]
	     */
	    function conforms(source) {
	      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
	    }
	
	    /**
	     * Creates a function that returns `value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Util
	     * @param {*} value The value to return from the new function.
	     * @returns {Function} Returns the new constant function.
	     * @example
	     *
	     * var objects = _.times(2, _.constant({ 'a': 1 }));
	     *
	     * console.log(objects);
	     * // => [{ 'a': 1 }, { 'a': 1 }]
	     *
	     * console.log(objects[0] === objects[1]);
	     * // => true
	     */
	    function constant(value) {
	      return function() {
	        return value;
	      };
	    }
	
	    /**
	     * Checks `value` to determine whether a default value should be returned in
	     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
	     * or `undefined`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.14.0
	     * @category Util
	     * @param {*} value The value to check.
	     * @param {*} defaultValue The default value.
	     * @returns {*} Returns the resolved value.
	     * @example
	     *
	     * _.defaultTo(1, 10);
	     * // => 1
	     *
	     * _.defaultTo(undefined, 10);
	     * // => 10
	     */
	    function defaultTo(value, defaultValue) {
	      return (value == null || value !== value) ? defaultValue : value;
	    }
	
	    /**
	     * Creates a function that returns the result of invoking the given functions
	     * with the `this` binding of the created function, where each successive
	     * invocation is supplied the return value of the previous.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [funcs] The functions to invoke.
	     * @returns {Function} Returns the new composite function.
	     * @see _.flowRight
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var addSquare = _.flow([_.add, square]);
	     * addSquare(1, 2);
	     * // => 9
	     */
	    var flow = createFlow();
	
	    /**
	     * This method is like `_.flow` except that it creates a function that
	     * invokes the given functions from right to left.
	     *
	     * @static
	     * @since 3.0.0
	     * @memberOf _
	     * @category Util
	     * @param {...(Function|Function[])} [funcs] The functions to invoke.
	     * @returns {Function} Returns the new composite function.
	     * @see _.flow
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var addSquare = _.flowRight([square, _.add]);
	     * addSquare(1, 2);
	     * // => 9
	     */
	    var flowRight = createFlow(true);
	
	    /**
	     * This method returns the first argument it receives.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {*} value Any value.
	     * @returns {*} Returns `value`.
	     * @example
	     *
	     * var object = { 'a': 1 };
	     *
	     * console.log(_.identity(object) === object);
	     * // => true
	     */
	    function identity(value) {
	      return value;
	    }
	
	    /**
	     * Creates a function that invokes `func` with the arguments of the created
	     * function. If `func` is a property name, the created function returns the
	     * property value for a given element. If `func` is an array or object, the
	     * created function returns `true` for elements that contain the equivalent
	     * source properties, otherwise it returns `false`.
	     *
	     * @static
	     * @since 4.0.0
	     * @memberOf _
	     * @category Util
	     * @param {*} [func=_.identity] The value to convert to a callback.
	     * @returns {Function} Returns the callback.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': true },
	     *   { 'user': 'fred',   'age': 40, 'active': false }
	     * ];
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
	     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.filter(users, _.iteratee(['user', 'fred']));
	     * // => [{ 'user': 'fred', 'age': 40 }]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.map(users, _.iteratee('user'));
	     * // => ['barney', 'fred']
	     *
	     * // Create custom iteratee shorthands.
	     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
	     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
	     *     return func.test(string);
	     *   };
	     * });
	     *
	     * _.filter(['abc', 'def'], /ef/);
	     * // => ['def']
	     */
	    function iteratee(func) {
	      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
	    }
	
	    /**
	     * Creates a function that performs a partial deep comparison between a given
	     * object and `source`, returning `true` if the given object has equivalent
	     * property values, else `false`.
	     *
	     * **Note:** The created function is equivalent to `_.isMatch` with `source`
	     * partially applied.
	     *
	     * Partial comparisons will match empty array and empty object `source`
	     * values against any array or object value, respectively. See `_.isEqual`
	     * for a list of supported value comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {Object} source The object of property values to match.
	     * @returns {Function} Returns the new spec function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': 1, 'b': 2, 'c': 3 },
	     *   { 'a': 4, 'b': 5, 'c': 6 }
	     * ];
	     *
	     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
	     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
	     */
	    function matches(source) {
	      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
	    }
	
	    /**
	     * Creates a function that performs a partial deep comparison between the
	     * value at `path` of a given object to `srcValue`, returning `true` if the
	     * object value is equivalent, else `false`.
	     *
	     * **Note:** Partial comparisons will match empty array and empty object
	     * `srcValue` values against any array or object value, respectively. See
	     * `_.isEqual` for a list of supported value comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.2.0
	     * @category Util
	     * @param {Array|string} path The path of the property to get.
	     * @param {*} srcValue The value to match.
	     * @returns {Function} Returns the new spec function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': 1, 'b': 2, 'c': 3 },
	     *   { 'a': 4, 'b': 5, 'c': 6 }
	     * ];
	     *
	     * _.find(objects, _.matchesProperty('a', 4));
	     * // => { 'a': 4, 'b': 5, 'c': 6 }
	     */
	    function matchesProperty(path, srcValue) {
	      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
	    }
	
	    /**
	     * Creates a function that invokes the method at `path` of a given object.
	     * Any additional arguments are provided to the invoked method.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.7.0
	     * @category Util
	     * @param {Array|string} path The path of the method to invoke.
	     * @param {...*} [args] The arguments to invoke the method with.
	     * @returns {Function} Returns the new invoker function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': { 'b': _.constant(2) } },
	     *   { 'a': { 'b': _.constant(1) } }
	     * ];
	     *
	     * _.map(objects, _.method('a.b'));
	     * // => [2, 1]
	     *
	     * _.map(objects, _.method(['a', 'b']));
	     * // => [2, 1]
	     */
	    var method = baseRest(function(path, args) {
	      return function(object) {
	        return baseInvoke(object, path, args);
	      };
	    });
	
	    /**
	     * The opposite of `_.method`; this method creates a function that invokes
	     * the method at a given path of `object`. Any additional arguments are
	     * provided to the invoked method.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.7.0
	     * @category Util
	     * @param {Object} object The object to query.
	     * @param {...*} [args] The arguments to invoke the method with.
	     * @returns {Function} Returns the new invoker function.
	     * @example
	     *
	     * var array = _.times(3, _.constant),
	     *     object = { 'a': array, 'b': array, 'c': array };
	     *
	     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
	     * // => [2, 0]
	     *
	     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
	     * // => [2, 0]
	     */
	    var methodOf = baseRest(function(object, args) {
	      return function(path) {
	        return baseInvoke(object, path, args);
	      };
	    });
	
	    /**
	     * Adds all own enumerable string keyed function properties of a source
	     * object to the destination object. If `object` is a function, then methods
	     * are added to its prototype as well.
	     *
	     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
	     * avoid conflicts caused by modifying the original.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {Function|Object} [object=lodash] The destination object.
	     * @param {Object} source The object of functions to add.
	     * @param {Object} [options={}] The options object.
	     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
	     * @returns {Function|Object} Returns `object`.
	     * @example
	     *
	     * function vowels(string) {
	     *   return _.filter(string, function(v) {
	     *     return /[aeiou]/i.test(v);
	     *   });
	     * }
	     *
	     * _.mixin({ 'vowels': vowels });
	     * _.vowels('fred');
	     * // => ['e']
	     *
	     * _('fred').vowels().value();
	     * // => ['e']
	     *
	     * _.mixin({ 'vowels': vowels }, { 'chain': false });
	     * _('fred').vowels();
	     * // => ['e']
	     */
	    function mixin(object, source, options) {
	      var props = keys(source),
	          methodNames = baseFunctions(source, props);
	
	      if (options == null &&
	          !(isObject(source) && (methodNames.length || !props.length))) {
	        options = source;
	        source = object;
	        object = this;
	        methodNames = baseFunctions(source, keys(source));
	      }
	      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
	          isFunc = isFunction(object);
	
	      arrayEach(methodNames, function(methodName) {
	        var func = source[methodName];
	        object[methodName] = func;
	        if (isFunc) {
	          object.prototype[methodName] = function() {
	            var chainAll = this.__chain__;
	            if (chain || chainAll) {
	              var result = object(this.__wrapped__),
	                  actions = result.__actions__ = copyArray(this.__actions__);
	
	              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
	              result.__chain__ = chainAll;
	              return result;
	            }
	            return func.apply(object, arrayPush([this.value()], arguments));
	          };
	        }
	      });
	
	      return object;
	    }
	
	    /**
	     * Reverts the `_` variable to its previous value and returns a reference to
	     * the `lodash` function.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @returns {Function} Returns the `lodash` function.
	     * @example
	     *
	     * var lodash = _.noConflict();
	     */
	    function noConflict() {
	      if (root._ === this) {
	        root._ = oldDash;
	      }
	      return this;
	    }
	
	    /**
	     * This method returns `undefined`.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.3.0
	     * @category Util
	     * @example
	     *
	     * _.times(2, _.noop);
	     * // => [undefined, undefined]
	     */
	    function noop() {
	      // No operation performed.
	    }
	
	    /**
	     * Creates a function that gets the argument at index `n`. If `n` is negative,
	     * the nth argument from the end is returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {number} [n=0] The index of the argument to return.
	     * @returns {Function} Returns the new pass-thru function.
	     * @example
	     *
	     * var func = _.nthArg(1);
	     * func('a', 'b', 'c', 'd');
	     * // => 'b'
	     *
	     * var func = _.nthArg(-2);
	     * func('a', 'b', 'c', 'd');
	     * // => 'c'
	     */
	    function nthArg(n) {
	      n = toInteger(n);
	      return baseRest(function(args) {
	        return baseNth(args, n);
	      });
	    }
	
	    /**
	     * Creates a function that invokes `iteratees` with the arguments it receives
	     * and returns their results.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [iteratees=[_.identity]]
	     *  The iteratees to invoke.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var func = _.over([Math.max, Math.min]);
	     *
	     * func(1, 2, 3, 4);
	     * // => [4, 1]
	     */
	    var over = createOver(arrayMap);
	
	    /**
	     * Creates a function that checks if **all** of the `predicates` return
	     * truthy when invoked with the arguments it receives.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [predicates=[_.identity]]
	     *  The predicates to check.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var func = _.overEvery([Boolean, isFinite]);
	     *
	     * func('1');
	     * // => true
	     *
	     * func(null);
	     * // => false
	     *
	     * func(NaN);
	     * // => false
	     */
	    var overEvery = createOver(arrayEvery);
	
	    /**
	     * Creates a function that checks if **any** of the `predicates` return
	     * truthy when invoked with the arguments it receives.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [predicates=[_.identity]]
	     *  The predicates to check.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var func = _.overSome([Boolean, isFinite]);
	     *
	     * func('1');
	     * // => true
	     *
	     * func(null);
	     * // => true
	     *
	     * func(NaN);
	     * // => false
	     */
	    var overSome = createOver(arraySome);
	
	    /**
	     * Creates a function that returns the value at `path` of a given object.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Util
	     * @param {Array|string} path The path of the property to get.
	     * @returns {Function} Returns the new accessor function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': { 'b': 2 } },
	     *   { 'a': { 'b': 1 } }
	     * ];
	     *
	     * _.map(objects, _.property('a.b'));
	     * // => [2, 1]
	     *
	     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
	     * // => [1, 2]
	     */
	    function property(path) {
	      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
	    }
	
	    /**
	     * The opposite of `_.property`; this method creates a function that returns
	     * the value at a given path of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {Object} object The object to query.
	     * @returns {Function} Returns the new accessor function.
	     * @example
	     *
	     * var array = [0, 1, 2],
	     *     object = { 'a': array, 'b': array, 'c': array };
	     *
	     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
	     * // => [2, 0]
	     *
	     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
	     * // => [2, 0]
	     */
	    function propertyOf(object) {
	      return function(path) {
	        return object == null ? undefined : baseGet(object, path);
	      };
	    }
	
	    /**
	     * Creates an array of numbers (positive and/or negative) progressing from
	     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
	     * `start` is specified without an `end` or `step`. If `end` is not specified,
	     * it's set to `start` with `start` then set to `0`.
	     *
	     * **Note:** JavaScript follows the IEEE-754 standard for resolving
	     * floating-point values which can produce unexpected results.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {number} [start=0] The start of the range.
	     * @param {number} end The end of the range.
	     * @param {number} [step=1] The value to increment or decrement by.
	     * @returns {Array} Returns the range of numbers.
	     * @see _.inRange, _.rangeRight
	     * @example
	     *
	     * _.range(4);
	     * // => [0, 1, 2, 3]
	     *
	     * _.range(-4);
	     * // => [0, -1, -2, -3]
	     *
	     * _.range(1, 5);
	     * // => [1, 2, 3, 4]
	     *
	     * _.range(0, 20, 5);
	     * // => [0, 5, 10, 15]
	     *
	     * _.range(0, -4, -1);
	     * // => [0, -1, -2, -3]
	     *
	     * _.range(1, 4, 0);
	     * // => [1, 1, 1]
	     *
	     * _.range(0);
	     * // => []
	     */
	    var range = createRange();
	
	    /**
	     * This method is like `_.range` except that it populates values in
	     * descending order.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {number} [start=0] The start of the range.
	     * @param {number} end The end of the range.
	     * @param {number} [step=1] The value to increment or decrement by.
	     * @returns {Array} Returns the range of numbers.
	     * @see _.inRange, _.range
	     * @example
	     *
	     * _.rangeRight(4);
	     * // => [3, 2, 1, 0]
	     *
	     * _.rangeRight(-4);
	     * // => [-3, -2, -1, 0]
	     *
	     * _.rangeRight(1, 5);
	     * // => [4, 3, 2, 1]
	     *
	     * _.rangeRight(0, 20, 5);
	     * // => [15, 10, 5, 0]
	     *
	     * _.rangeRight(0, -4, -1);
	     * // => [-3, -2, -1, 0]
	     *
	     * _.rangeRight(1, 4, 0);
	     * // => [1, 1, 1]
	     *
	     * _.rangeRight(0);
	     * // => []
	     */
	    var rangeRight = createRange(true);
	
	    /**
	     * This method returns a new empty array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {Array} Returns the new empty array.
	     * @example
	     *
	     * var arrays = _.times(2, _.stubArray);
	     *
	     * console.log(arrays);
	     * // => [[], []]
	     *
	     * console.log(arrays[0] === arrays[1]);
	     * // => false
	     */
	    function stubArray() {
	      return [];
	    }
	
	    /**
	     * This method returns `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {boolean} Returns `false`.
	     * @example
	     *
	     * _.times(2, _.stubFalse);
	     * // => [false, false]
	     */
	    function stubFalse() {
	      return false;
	    }
	
	    /**
	     * This method returns a new empty object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {Object} Returns the new empty object.
	     * @example
	     *
	     * var objects = _.times(2, _.stubObject);
	     *
	     * console.log(objects);
	     * // => [{}, {}]
	     *
	     * console.log(objects[0] === objects[1]);
	     * // => false
	     */
	    function stubObject() {
	      return {};
	    }
	
	    /**
	     * This method returns an empty string.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {string} Returns the empty string.
	     * @example
	     *
	     * _.times(2, _.stubString);
	     * // => ['', '']
	     */
	    function stubString() {
	      return '';
	    }
	
	    /**
	     * This method returns `true`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {boolean} Returns `true`.
	     * @example
	     *
	     * _.times(2, _.stubTrue);
	     * // => [true, true]
	     */
	    function stubTrue() {
	      return true;
	    }
	
	    /**
	     * Invokes the iteratee `n` times, returning an array of the results of
	     * each invocation. The iteratee is invoked with one argument; (index).
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {number} n The number of times to invoke `iteratee`.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the array of results.
	     * @example
	     *
	     * _.times(3, String);
	     * // => ['0', '1', '2']
	     *
	     *  _.times(4, _.constant(0));
	     * // => [0, 0, 0, 0]
	     */
	    function times(n, iteratee) {
	      n = toInteger(n);
	      if (n < 1 || n > MAX_SAFE_INTEGER) {
	        return [];
	      }
	      var index = MAX_ARRAY_LENGTH,
	          length = nativeMin(n, MAX_ARRAY_LENGTH);
	
	      iteratee = getIteratee(iteratee);
	      n -= MAX_ARRAY_LENGTH;
	
	      var result = baseTimes(length, iteratee);
	      while (++index < n) {
	        iteratee(index);
	      }
	      return result;
	    }
	
	    /**
	     * Converts `value` to a property path array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {*} value The value to convert.
	     * @returns {Array} Returns the new property path array.
	     * @example
	     *
	     * _.toPath('a.b.c');
	     * // => ['a', 'b', 'c']
	     *
	     * _.toPath('a[0].b.c');
	     * // => ['a', '0', 'b', 'c']
	     */
	    function toPath(value) {
	      if (isArray(value)) {
	        return arrayMap(value, toKey);
	      }
	      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
	    }
	
	    /**
	     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {string} [prefix=''] The value to prefix the ID with.
	     * @returns {string} Returns the unique ID.
	     * @example
	     *
	     * _.uniqueId('contact_');
	     * // => 'contact_104'
	     *
	     * _.uniqueId();
	     * // => '105'
	     */
	    function uniqueId(prefix) {
	      var id = ++idCounter;
	      return toString(prefix) + id;
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Adds two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.4.0
	     * @category Math
	     * @param {number} augend The first number in an addition.
	     * @param {number} addend The second number in an addition.
	     * @returns {number} Returns the total.
	     * @example
	     *
	     * _.add(6, 4);
	     * // => 10
	     */
	    var add = createMathOperation(function(augend, addend) {
	      return augend + addend;
	    }, 0);
	
	    /**
	     * Computes `number` rounded up to `precision`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Math
	     * @param {number} number The number to round up.
	     * @param {number} [precision=0] The precision to round up to.
	     * @returns {number} Returns the rounded up number.
	     * @example
	     *
	     * _.ceil(4.006);
	     * // => 5
	     *
	     * _.ceil(6.004, 2);
	     * // => 6.01
	     *
	     * _.ceil(6040, -2);
	     * // => 6100
	     */
	    var ceil = createRound('ceil');
	
	    /**
	     * Divide two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Math
	     * @param {number} dividend The first number in a division.
	     * @param {number} divisor The second number in a division.
	     * @returns {number} Returns the quotient.
	     * @example
	     *
	     * _.divide(6, 4);
	     * // => 1.5
	     */
	    var divide = createMathOperation(function(dividend, divisor) {
	      return dividend / divisor;
	    }, 1);
	
	    /**
	     * Computes `number` rounded down to `precision`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Math
	     * @param {number} number The number to round down.
	     * @param {number} [precision=0] The precision to round down to.
	     * @returns {number} Returns the rounded down number.
	     * @example
	     *
	     * _.floor(4.006);
	     * // => 4
	     *
	     * _.floor(0.046, 2);
	     * // => 0.04
	     *
	     * _.floor(4060, -2);
	     * // => 4000
	     */
	    var floor = createRound('floor');
	
	    /**
	     * Computes the maximum value of `array`. If `array` is empty or falsey,
	     * `undefined` is returned.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {*} Returns the maximum value.
	     * @example
	     *
	     * _.max([4, 2, 8, 6]);
	     * // => 8
	     *
	     * _.max([]);
	     * // => undefined
	     */
	    function max(array) {
	      return (array && array.length)
	        ? baseExtremum(array, identity, baseGt)
	        : undefined;
	    }
	
	    /**
	     * This method is like `_.max` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the criterion by which
	     * the value is ranked. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {*} Returns the maximum value.
	     * @example
	     *
	     * var objects = [{ 'n': 1 }, { 'n': 2 }];
	     *
	     * _.maxBy(objects, function(o) { return o.n; });
	     * // => { 'n': 2 }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.maxBy(objects, 'n');
	     * // => { 'n': 2 }
	     */
	    function maxBy(array, iteratee) {
	      return (array && array.length)
	        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
	        : undefined;
	    }
	
	    /**
	     * Computes the mean of the values in `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {number} Returns the mean.
	     * @example
	     *
	     * _.mean([4, 2, 8, 6]);
	     * // => 5
	     */
	    function mean(array) {
	      return baseMean(array, identity);
	    }
	
	    /**
	     * This method is like `_.mean` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the value to be averaged.
	     * The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {number} Returns the mean.
	     * @example
	     *
	     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
	     *
	     * _.meanBy(objects, function(o) { return o.n; });
	     * // => 5
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.meanBy(objects, 'n');
	     * // => 5
	     */
	    function meanBy(array, iteratee) {
	      return baseMean(array, getIteratee(iteratee, 2));
	    }
	
	    /**
	     * Computes the minimum value of `array`. If `array` is empty or falsey,
	     * `undefined` is returned.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {*} Returns the minimum value.
	     * @example
	     *
	     * _.min([4, 2, 8, 6]);
	     * // => 2
	     *
	     * _.min([]);
	     * // => undefined
	     */
	    function min(array) {
	      return (array && array.length)
	        ? baseExtremum(array, identity, baseLt)
	        : undefined;
	    }
	
	    /**
	     * This method is like `_.min` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the criterion by which
	     * the value is ranked. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {*} Returns the minimum value.
	     * @example
	     *
	     * var objects = [{ 'n': 1 }, { 'n': 2 }];
	     *
	     * _.minBy(objects, function(o) { return o.n; });
	     * // => { 'n': 1 }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.minBy(objects, 'n');
	     * // => { 'n': 1 }
	     */
	    function minBy(array, iteratee) {
	      return (array && array.length)
	        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
	        : undefined;
	    }
	
	    /**
	     * Multiply two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Math
	     * @param {number} multiplier The first number in a multiplication.
	     * @param {number} multiplicand The second number in a multiplication.
	     * @returns {number} Returns the product.
	     * @example
	     *
	     * _.multiply(6, 4);
	     * // => 24
	     */
	    var multiply = createMathOperation(function(multiplier, multiplicand) {
	      return multiplier * multiplicand;
	    }, 1);
	
	    /**
	     * Computes `number` rounded to `precision`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Math
	     * @param {number} number The number to round.
	     * @param {number} [precision=0] The precision to round to.
	     * @returns {number} Returns the rounded number.
	     * @example
	     *
	     * _.round(4.006);
	     * // => 4
	     *
	     * _.round(4.006, 2);
	     * // => 4.01
	     *
	     * _.round(4060, -2);
	     * // => 4100
	     */
	    var round = createRound('round');
	
	    /**
	     * Subtract two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {number} minuend The first number in a subtraction.
	     * @param {number} subtrahend The second number in a subtraction.
	     * @returns {number} Returns the difference.
	     * @example
	     *
	     * _.subtract(6, 4);
	     * // => 2
	     */
	    var subtract = createMathOperation(function(minuend, subtrahend) {
	      return minuend - subtrahend;
	    }, 0);
	
	    /**
	     * Computes the sum of the values in `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.4.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {number} Returns the sum.
	     * @example
	     *
	     * _.sum([4, 2, 8, 6]);
	     * // => 20
	     */
	    function sum(array) {
	      return (array && array.length)
	        ? baseSum(array, identity)
	        : 0;
	    }
	
	    /**
	     * This method is like `_.sum` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the value to be summed.
	     * The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {number} Returns the sum.
	     * @example
	     *
	     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
	     *
	     * _.sumBy(objects, function(o) { return o.n; });
	     * // => 20
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.sumBy(objects, 'n');
	     * // => 20
	     */
	    function sumBy(array, iteratee) {
	      return (array && array.length)
	        ? baseSum(array, getIteratee(iteratee, 2))
	        : 0;
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    // Add methods that return wrapped values in chain sequences.
	    lodash.after = after;
	    lodash.ary = ary;
	    lodash.assign = assign;
	    lodash.assignIn = assignIn;
	    lodash.assignInWith = assignInWith;
	    lodash.assignWith = assignWith;
	    lodash.at = at;
	    lodash.before = before;
	    lodash.bind = bind;
	    lodash.bindAll = bindAll;
	    lodash.bindKey = bindKey;
	    lodash.castArray = castArray;
	    lodash.chain = chain;
	    lodash.chunk = chunk;
	    lodash.compact = compact;
	    lodash.concat = concat;
	    lodash.cond = cond;
	    lodash.conforms = conforms;
	    lodash.constant = constant;
	    lodash.countBy = countBy;
	    lodash.create = create;
	    lodash.curry = curry;
	    lodash.curryRight = curryRight;
	    lodash.debounce = debounce;
	    lodash.defaults = defaults;
	    lodash.defaultsDeep = defaultsDeep;
	    lodash.defer = defer;
	    lodash.delay = delay;
	    lodash.difference = difference;
	    lodash.differenceBy = differenceBy;
	    lodash.differenceWith = differenceWith;
	    lodash.drop = drop;
	    lodash.dropRight = dropRight;
	    lodash.dropRightWhile = dropRightWhile;
	    lodash.dropWhile = dropWhile;
	    lodash.fill = fill;
	    lodash.filter = filter;
	    lodash.flatMap = flatMap;
	    lodash.flatMapDeep = flatMapDeep;
	    lodash.flatMapDepth = flatMapDepth;
	    lodash.flatten = flatten;
	    lodash.flattenDeep = flattenDeep;
	    lodash.flattenDepth = flattenDepth;
	    lodash.flip = flip;
	    lodash.flow = flow;
	    lodash.flowRight = flowRight;
	    lodash.fromPairs = fromPairs;
	    lodash.functions = functions;
	    lodash.functionsIn = functionsIn;
	    lodash.groupBy = groupBy;
	    lodash.initial = initial;
	    lodash.intersection = intersection;
	    lodash.intersectionBy = intersectionBy;
	    lodash.intersectionWith = intersectionWith;
	    lodash.invert = invert;
	    lodash.invertBy = invertBy;
	    lodash.invokeMap = invokeMap;
	    lodash.iteratee = iteratee;
	    lodash.keyBy = keyBy;
	    lodash.keys = keys;
	    lodash.keysIn = keysIn;
	    lodash.map = map;
	    lodash.mapKeys = mapKeys;
	    lodash.mapValues = mapValues;
	    lodash.matches = matches;
	    lodash.matchesProperty = matchesProperty;
	    lodash.memoize = memoize;
	    lodash.merge = merge;
	    lodash.mergeWith = mergeWith;
	    lodash.method = method;
	    lodash.methodOf = methodOf;
	    lodash.mixin = mixin;
	    lodash.negate = negate;
	    lodash.nthArg = nthArg;
	    lodash.omit = omit;
	    lodash.omitBy = omitBy;
	    lodash.once = once;
	    lodash.orderBy = orderBy;
	    lodash.over = over;
	    lodash.overArgs = overArgs;
	    lodash.overEvery = overEvery;
	    lodash.overSome = overSome;
	    lodash.partial = partial;
	    lodash.partialRight = partialRight;
	    lodash.partition = partition;
	    lodash.pick = pick;
	    lodash.pickBy = pickBy;
	    lodash.property = property;
	    lodash.propertyOf = propertyOf;
	    lodash.pull = pull;
	    lodash.pullAll = pullAll;
	    lodash.pullAllBy = pullAllBy;
	    lodash.pullAllWith = pullAllWith;
	    lodash.pullAt = pullAt;
	    lodash.range = range;
	    lodash.rangeRight = rangeRight;
	    lodash.rearg = rearg;
	    lodash.reject = reject;
	    lodash.remove = remove;
	    lodash.rest = rest;
	    lodash.reverse = reverse;
	    lodash.sampleSize = sampleSize;
	    lodash.set = set;
	    lodash.setWith = setWith;
	    lodash.shuffle = shuffle;
	    lodash.slice = slice;
	    lodash.sortBy = sortBy;
	    lodash.sortedUniq = sortedUniq;
	    lodash.sortedUniqBy = sortedUniqBy;
	    lodash.split = split;
	    lodash.spread = spread;
	    lodash.tail = tail;
	    lodash.take = take;
	    lodash.takeRight = takeRight;
	    lodash.takeRightWhile = takeRightWhile;
	    lodash.takeWhile = takeWhile;
	    lodash.tap = tap;
	    lodash.throttle = throttle;
	    lodash.thru = thru;
	    lodash.toArray = toArray;
	    lodash.toPairs = toPairs;
	    lodash.toPairsIn = toPairsIn;
	    lodash.toPath = toPath;
	    lodash.toPlainObject = toPlainObject;
	    lodash.transform = transform;
	    lodash.unary = unary;
	    lodash.union = union;
	    lodash.unionBy = unionBy;
	    lodash.unionWith = unionWith;
	    lodash.uniq = uniq;
	    lodash.uniqBy = uniqBy;
	    lodash.uniqWith = uniqWith;
	    lodash.unset = unset;
	    lodash.unzip = unzip;
	    lodash.unzipWith = unzipWith;
	    lodash.update = update;
	    lodash.updateWith = updateWith;
	    lodash.values = values;
	    lodash.valuesIn = valuesIn;
	    lodash.without = without;
	    lodash.words = words;
	    lodash.wrap = wrap;
	    lodash.xor = xor;
	    lodash.xorBy = xorBy;
	    lodash.xorWith = xorWith;
	    lodash.zip = zip;
	    lodash.zipObject = zipObject;
	    lodash.zipObjectDeep = zipObjectDeep;
	    lodash.zipWith = zipWith;
	
	    // Add aliases.
	    lodash.entries = toPairs;
	    lodash.entriesIn = toPairsIn;
	    lodash.extend = assignIn;
	    lodash.extendWith = assignInWith;
	
	    // Add methods to `lodash.prototype`.
	    mixin(lodash, lodash);
	
	    /*------------------------------------------------------------------------*/
	
	    // Add methods that return unwrapped values in chain sequences.
	    lodash.add = add;
	    lodash.attempt = attempt;
	    lodash.camelCase = camelCase;
	    lodash.capitalize = capitalize;
	    lodash.ceil = ceil;
	    lodash.clamp = clamp;
	    lodash.clone = clone;
	    lodash.cloneDeep = cloneDeep;
	    lodash.cloneDeepWith = cloneDeepWith;
	    lodash.cloneWith = cloneWith;
	    lodash.conformsTo = conformsTo;
	    lodash.deburr = deburr;
	    lodash.defaultTo = defaultTo;
	    lodash.divide = divide;
	    lodash.endsWith = endsWith;
	    lodash.eq = eq;
	    lodash.escape = escape;
	    lodash.escapeRegExp = escapeRegExp;
	    lodash.every = every;
	    lodash.find = find;
	    lodash.findIndex = findIndex;
	    lodash.findKey = findKey;
	    lodash.findLast = findLast;
	    lodash.findLastIndex = findLastIndex;
	    lodash.findLastKey = findLastKey;
	    lodash.floor = floor;
	    lodash.forEach = forEach;
	    lodash.forEachRight = forEachRight;
	    lodash.forIn = forIn;
	    lodash.forInRight = forInRight;
	    lodash.forOwn = forOwn;
	    lodash.forOwnRight = forOwnRight;
	    lodash.get = get;
	    lodash.gt = gt;
	    lodash.gte = gte;
	    lodash.has = has;
	    lodash.hasIn = hasIn;
	    lodash.head = head;
	    lodash.identity = identity;
	    lodash.includes = includes;
	    lodash.indexOf = indexOf;
	    lodash.inRange = inRange;
	    lodash.invoke = invoke;
	    lodash.isArguments = isArguments;
	    lodash.isArray = isArray;
	    lodash.isArrayBuffer = isArrayBuffer;
	    lodash.isArrayLike = isArrayLike;
	    lodash.isArrayLikeObject = isArrayLikeObject;
	    lodash.isBoolean = isBoolean;
	    lodash.isBuffer = isBuffer;
	    lodash.isDate = isDate;
	    lodash.isElement = isElement;
	    lodash.isEmpty = isEmpty;
	    lodash.isEqual = isEqual;
	    lodash.isEqualWith = isEqualWith;
	    lodash.isError = isError;
	    lodash.isFinite = isFinite;
	    lodash.isFunction = isFunction;
	    lodash.isInteger = isInteger;
	    lodash.isLength = isLength;
	    lodash.isMap = isMap;
	    lodash.isMatch = isMatch;
	    lodash.isMatchWith = isMatchWith;
	    lodash.isNaN = isNaN;
	    lodash.isNative = isNative;
	    lodash.isNil = isNil;
	    lodash.isNull = isNull;
	    lodash.isNumber = isNumber;
	    lodash.isObject = isObject;
	    lodash.isObjectLike = isObjectLike;
	    lodash.isPlainObject = isPlainObject;
	    lodash.isRegExp = isRegExp;
	    lodash.isSafeInteger = isSafeInteger;
	    lodash.isSet = isSet;
	    lodash.isString = isString;
	    lodash.isSymbol = isSymbol;
	    lodash.isTypedArray = isTypedArray;
	    lodash.isUndefined = isUndefined;
	    lodash.isWeakMap = isWeakMap;
	    lodash.isWeakSet = isWeakSet;
	    lodash.join = join;
	    lodash.kebabCase = kebabCase;
	    lodash.last = last;
	    lodash.lastIndexOf = lastIndexOf;
	    lodash.lowerCase = lowerCase;
	    lodash.lowerFirst = lowerFirst;
	    lodash.lt = lt;
	    lodash.lte = lte;
	    lodash.max = max;
	    lodash.maxBy = maxBy;
	    lodash.mean = mean;
	    lodash.meanBy = meanBy;
	    lodash.min = min;
	    lodash.minBy = minBy;
	    lodash.stubArray = stubArray;
	    lodash.stubFalse = stubFalse;
	    lodash.stubObject = stubObject;
	    lodash.stubString = stubString;
	    lodash.stubTrue = stubTrue;
	    lodash.multiply = multiply;
	    lodash.nth = nth;
	    lodash.noConflict = noConflict;
	    lodash.noop = noop;
	    lodash.now = now;
	    lodash.pad = pad;
	    lodash.padEnd = padEnd;
	    lodash.padStart = padStart;
	    lodash.parseInt = parseInt;
	    lodash.random = random;
	    lodash.reduce = reduce;
	    lodash.reduceRight = reduceRight;
	    lodash.repeat = repeat;
	    lodash.replace = replace;
	    lodash.result = result;
	    lodash.round = round;
	    lodash.runInContext = runInContext;
	    lodash.sample = sample;
	    lodash.size = size;
	    lodash.snakeCase = snakeCase;
	    lodash.some = some;
	    lodash.sortedIndex = sortedIndex;
	    lodash.sortedIndexBy = sortedIndexBy;
	    lodash.sortedIndexOf = sortedIndexOf;
	    lodash.sortedLastIndex = sortedLastIndex;
	    lodash.sortedLastIndexBy = sortedLastIndexBy;
	    lodash.sortedLastIndexOf = sortedLastIndexOf;
	    lodash.startCase = startCase;
	    lodash.startsWith = startsWith;
	    lodash.subtract = subtract;
	    lodash.sum = sum;
	    lodash.sumBy = sumBy;
	    lodash.template = template;
	    lodash.times = times;
	    lodash.toFinite = toFinite;
	    lodash.toInteger = toInteger;
	    lodash.toLength = toLength;
	    lodash.toLower = toLower;
	    lodash.toNumber = toNumber;
	    lodash.toSafeInteger = toSafeInteger;
	    lodash.toString = toString;
	    lodash.toUpper = toUpper;
	    lodash.trim = trim;
	    lodash.trimEnd = trimEnd;
	    lodash.trimStart = trimStart;
	    lodash.truncate = truncate;
	    lodash.unescape = unescape;
	    lodash.uniqueId = uniqueId;
	    lodash.upperCase = upperCase;
	    lodash.upperFirst = upperFirst;
	
	    // Add aliases.
	    lodash.each = forEach;
	    lodash.eachRight = forEachRight;
	    lodash.first = head;
	
	    mixin(lodash, (function() {
	      var source = {};
	      baseForOwn(lodash, function(func, methodName) {
	        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
	          source[methodName] = func;
	        }
	      });
	      return source;
	    }()), { 'chain': false });
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * The semantic version number.
	     *
	     * @static
	     * @memberOf _
	     * @type {string}
	     */
	    lodash.VERSION = VERSION;
	
	    // Assign default placeholders.
	    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
	      lodash[methodName].placeholder = lodash;
	    });
	
	    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
	    arrayEach(['drop', 'take'], function(methodName, index) {
	      LazyWrapper.prototype[methodName] = function(n) {
	        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
	
	        var result = (this.__filtered__ && !index)
	          ? new LazyWrapper(this)
	          : this.clone();
	
	        if (result.__filtered__) {
	          result.__takeCount__ = nativeMin(n, result.__takeCount__);
	        } else {
	          result.__views__.push({
	            'size': nativeMin(n, MAX_ARRAY_LENGTH),
	            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
	          });
	        }
	        return result;
	      };
	
	      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
	        return this.reverse()[methodName](n).reverse();
	      };
	    });
	
	    // Add `LazyWrapper` methods that accept an `iteratee` value.
	    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
	      var type = index + 1,
	          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
	
	      LazyWrapper.prototype[methodName] = function(iteratee) {
	        var result = this.clone();
	        result.__iteratees__.push({
	          'iteratee': getIteratee(iteratee, 3),
	          'type': type
	        });
	        result.__filtered__ = result.__filtered__ || isFilter;
	        return result;
	      };
	    });
	
	    // Add `LazyWrapper` methods for `_.head` and `_.last`.
	    arrayEach(['head', 'last'], function(methodName, index) {
	      var takeName = 'take' + (index ? 'Right' : '');
	
	      LazyWrapper.prototype[methodName] = function() {
	        return this[takeName](1).value()[0];
	      };
	    });
	
	    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
	    arrayEach(['initial', 'tail'], function(methodName, index) {
	      var dropName = 'drop' + (index ? '' : 'Right');
	
	      LazyWrapper.prototype[methodName] = function() {
	        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
	      };
	    });
	
	    LazyWrapper.prototype.compact = function() {
	      return this.filter(identity);
	    };
	
	    LazyWrapper.prototype.find = function(predicate) {
	      return this.filter(predicate).head();
	    };
	
	    LazyWrapper.prototype.findLast = function(predicate) {
	      return this.reverse().find(predicate);
	    };
	
	    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
	      if (typeof path == 'function') {
	        return new LazyWrapper(this);
	      }
	      return this.map(function(value) {
	        return baseInvoke(value, path, args);
	      });
	    });
	
	    LazyWrapper.prototype.reject = function(predicate) {
	      return this.filter(negate(getIteratee(predicate)));
	    };
	
	    LazyWrapper.prototype.slice = function(start, end) {
	      start = toInteger(start);
	
	      var result = this;
	      if (result.__filtered__ && (start > 0 || end < 0)) {
	        return new LazyWrapper(result);
	      }
	      if (start < 0) {
	        result = result.takeRight(-start);
	      } else if (start) {
	        result = result.drop(start);
	      }
	      if (end !== undefined) {
	        end = toInteger(end);
	        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
	      }
	      return result;
	    };
	
	    LazyWrapper.prototype.takeRightWhile = function(predicate) {
	      return this.reverse().takeWhile(predicate).reverse();
	    };
	
	    LazyWrapper.prototype.toArray = function() {
	      return this.take(MAX_ARRAY_LENGTH);
	    };
	
	    // Add `LazyWrapper` methods to `lodash.prototype`.
	    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
	      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
	          isTaker = /^(?:head|last)$/.test(methodName),
	          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
	          retUnwrapped = isTaker || /^find/.test(methodName);
	
	      if (!lodashFunc) {
	        return;
	      }
	      lodash.prototype[methodName] = function() {
	        var value = this.__wrapped__,
	            args = isTaker ? [1] : arguments,
	            isLazy = value instanceof LazyWrapper,
	            iteratee = args[0],
	            useLazy = isLazy || isArray(value);
	
	        var interceptor = function(value) {
	          var result = lodashFunc.apply(lodash, arrayPush([value], args));
	          return (isTaker && chainAll) ? result[0] : result;
	        };
	
	        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
	          // Avoid lazy use if the iteratee has a "length" value other than `1`.
	          isLazy = useLazy = false;
	        }
	        var chainAll = this.__chain__,
	            isHybrid = !!this.__actions__.length,
	            isUnwrapped = retUnwrapped && !chainAll,
	            onlyLazy = isLazy && !isHybrid;
	
	        if (!retUnwrapped && useLazy) {
	          value = onlyLazy ? value : new LazyWrapper(this);
	          var result = func.apply(value, args);
	          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
	          return new LodashWrapper(result, chainAll);
	        }
	        if (isUnwrapped && onlyLazy) {
	          return func.apply(this, args);
	        }
	        result = this.thru(interceptor);
	        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
	      };
	    });
	
	    // Add `Array` methods to `lodash.prototype`.
	    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
	      var func = arrayProto[methodName],
	          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
	          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
	
	      lodash.prototype[methodName] = function() {
	        var args = arguments;
	        if (retUnwrapped && !this.__chain__) {
	          var value = this.value();
	          return func.apply(isArray(value) ? value : [], args);
	        }
	        return this[chainName](function(value) {
	          return func.apply(isArray(value) ? value : [], args);
	        });
	      };
	    });
	
	    // Map minified method names to their real names.
	    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
	      var lodashFunc = lodash[methodName];
	      if (lodashFunc) {
	        var key = (lodashFunc.name + ''),
	            names = realNames[key] || (realNames[key] = []);
	
	        names.push({ 'name': methodName, 'func': lodashFunc });
	      }
	    });
	
	    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
	      'name': 'wrapper',
	      'func': undefined
	    }];
	
	    // Add methods to `LazyWrapper`.
	    LazyWrapper.prototype.clone = lazyClone;
	    LazyWrapper.prototype.reverse = lazyReverse;
	    LazyWrapper.prototype.value = lazyValue;
	
	    // Add chain sequence methods to the `lodash` wrapper.
	    lodash.prototype.at = wrapperAt;
	    lodash.prototype.chain = wrapperChain;
	    lodash.prototype.commit = wrapperCommit;
	    lodash.prototype.next = wrapperNext;
	    lodash.prototype.plant = wrapperPlant;
	    lodash.prototype.reverse = wrapperReverse;
	    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
	
	    // Add lazy aliases.
	    lodash.prototype.first = lodash.prototype.head;
	
	    if (symIterator) {
	      lodash.prototype[symIterator] = wrapperToIterator;
	    }
	    return lodash;
	  });
	
	  /*--------------------------------------------------------------------------*/
	
	  // Export lodash.
	  var _ = runInContext();
	
	  // Some AMD build optimizers, like r.js, check for condition patterns like:
	  if (true) {
	    // Expose Lodash on the global object to prevent errors when Lodash is
	    // loaded by a script tag in the presence of an AMD loader.
	    // See http://requirejs.org/docs/errors.html#mismatch for more details.
	    // Use `_.noConflict` to remove Lodash from the global object.
	    root._ = _;
	
	    // Define as an anonymous module so, through path mapping, it can be
	    // referenced as the "underscore" module.
	    !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
	      return _;
	    }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
	  // Check for `exports` after `define` in case a build optimizer adds it.
	  else if (freeModule) {
	    // Export for Node.js.
	    (freeModule.exports = _)._ = _;
	    // Export for CommonJS support.
	    freeExports._ = _;
	  }
	  else {
	    // Export to the global object.
	    root._ = _;
	  }
	}.call(this));
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(145)(module)))

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

	/* WEBPACK VAR INJECTION */(function(process) {/*!
	 * (The MIT License)
	 * 
	 * Copyright (c) 2012-2014 Marcin Warpechowski
	 * Copyright (c) 2015 Handsoncode sp. z o.o. <hello@handsoncode.net>
	 * 
	 * Permission is hereby granted, free of charge, to any person obtaining
	 * a copy of this software and associated documentation files (the
	 * 'Software'), to deal in the Software without restriction, including
	 * without limitation the rights to use, copy, modify, merge, publish,
	 * distribute, sublicense, and/or sell copies of the Software, and to
	 * permit persons to whom the Software is furnished to do so, subject to
	 * the following conditions:
	 * 
	 * The above copyright notice and this permission notice shall be
	 * included in all copies or substantial portions of the Software.
	 * 
	 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
	 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
	 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
	 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
	 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
	 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
	 * 
	 * Version: 0.34.5
	 * Release date: 12/10/2017 (built at 12/10/2017 10:04:29)
	 */
	(function webpackUniversalModuleDefinition(root, factory) {
		if(true)
			module.exports = factory(__webpack_require__(234), __webpack_require__(351), __webpack_require__(413));
		else if(typeof define === 'function' && define.amd)
			define("Handsontable", ["moment", "numbro", "pikaday"], factory);
		else if(typeof exports === 'object')
			exports["Handsontable"] = factory(require("moment"), require("numbro"), require("pikaday"));
		else
			root["Handsontable"] = factory(root["moment"], root["numbro"], root["Pikaday"]);
	})(this, function(__WEBPACK_EXTERNAL_MODULE_50__, __WEBPACK_EXTERNAL_MODULE_80__, __WEBPACK_EXTERNAL_MODULE_213__) {
	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 = 180);
	/******/ })
	/************************************************************************/
	/******/ ([
	/* 0 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.HTML_CHARACTERS = undefined;
	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.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;
	
	var _browser = __webpack_require__(26);
	
	var _feature = __webpack_require__(34);
	
	/**
	 * 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;
	
	  while (element != null) {
	    if (iteration === level) {
	      parent = element;
	      break;
	    }
	
	    if (element.host && element.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
	      element = element.host;
	    } else {
	      iteration++;
	      element = element.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) {
	  while (element != null && element !== until) {
	    if (element.nodeType === Node.ELEMENT_NODE && (nodes.indexOf(element.nodeName) > -1 || nodes.indexOf(element) > -1)) {
	      return element;
	    }
	    if (element.host && element.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
	      element = element.host;
	    } else {
	      element = element.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 = [];
	
	  while (element) {
	    element = closest(element, nodes, until);
	
	    if (!element || until && !until.contains(element)) {
	      break;
	    }
	    matched.push(element);
	
	    if (element.host && element.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
	      element = element.host;
	    } else {
	      element = element.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(document.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',
	      result = false,
	      parentNode;
	
	  parentNode = polymerWrap(element);
	
	  function isHotTable(element) {
	    return element.nodeType === Node.ELEMENT_NODE && element.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;
	}
	
	/**
	 * Wrap element into polymer/webcomponent container if exists
	 *
	 * @param element
	 * @returns {*}
	 */
	function polymerWrap(element) {
	  /* global Polymer */
	  return typeof Polymer !== 'undefined' && typeof wrap === 'function' ? wrap(element) : element;
	}
	
	/**
	 * Unwrap element from polymer/webcomponent container if exists
	 *
	 * @param element
	 * @returns {*}
	 */
	function polymerUnwrap(element) {
	  /* global Polymer */
	  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;
	
	  if (element.previousSibling) {
	    /* eslint-disable no-cond-assign */
	    while (element = element.previousSibling) {
	      ++i;
	    }
	  }
	
	  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 = document.querySelector('.ht_clone_' + overlayType);
	  return overlayElement ? overlayElement.contains(element) : null;
	}
	
	var classListSupport = !!document.documentElement.classList;
	var _hasClass, _addClass, _removeClass;
	
	function filterEmptyClassNames(classNames) {
	  var len = 0,
	      result = [];
	
	  if (!classNames || !classNames.length) {
	    return result;
	  }
	  while (classNames[len]) {
	    result.push(classNames[len]);
	    len++;
	  }
	
	  return result;
	}
	
	if (classListSupport) {
	  var isSupportMultipleClassesArg = function () {
	    var element = document.createElement('div');
	
	    element.classList.add('test', 'test2');
	
	    return element.classList.contains('test2');
	  }();
	
	  _hasClass = function _hasClass(element, className) {
	    if (element.classList === void 0 || className === '') {
	      return false;
	    }
	
	    return element.classList.contains(className);
	  };
	
	  _addClass = function _addClass(element, className) {
	    var len = 0;
	
	    if (typeof className === 'string') {
	      className = className.split(' ');
	    }
	    className = filterEmptyClassNames(className);
	
	    if (isSupportMultipleClassesArg) {
	      element.classList.add.apply(element.classList, className);
	    } else {
	      while (className && className[len]) {
	        element.classList.add(className[len]);
	        len++;
	      }
	    }
	  };
	
	  _removeClass = function _removeClass(element, className) {
	    var len = 0;
	
	    if (typeof className === 'string') {
	      className = className.split(' ');
	    }
	    className = filterEmptyClassNames(className);
	
	    if (isSupportMultipleClassesArg) {
	      element.classList.remove.apply(element.classList, className);
	    } else {
	      while (className && className[len]) {
	        element.classList.remove(className[len]);
	        len++;
	      }
	    }
	  };
	} else {
	  var createClassNameRegExp = function createClassNameRegExp(className) {
	    return new RegExp('(\\s|^)' + 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, className) {
	    var len = 0,
	        _className = element.className;
	
	    if (typeof className === 'string') {
	      className = className.split(' ');
	    }
	    if (_className === '') {
	      _className = className.join(' ');
	    } else {
	      while (className && className[len]) {
	        if (!createClassNameRegExp(className[len]).test(_className)) {
	          _className += ' ' + className[len];
	        }
	        len++;
	      }
	    }
	    element.className = _className;
	  };
	
	  _removeClass = function _removeClass(element, className) {
	    var len = 0,
	        _className = element.className;
	
	    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++;
	    }
	    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 = exports.HTML_CHARACTERS = /(<(.*)>|&(.*);)/;
	
	/**
	 * Insert content into element trying avoid innerHTML method.
	 * @return {void}
	 */
	function fastInnerHTML(element, content) {
	  if (HTML_CHARACTERS.test(content)) {
	    element.innerHTML = content;
	  } else {
	    fastInnerText(element, content);
	  }
	}
	
	/**
	 * Insert text content into element
	 * @return {void}
	 */
	
	var textContextSupport = !!document.createTextNode('test').textContent;
	
	function fastInnerText(element, content) {
	  var child = element.firstChild;
	
	  if (child && child.nodeType === 3 && child.nextSibling === null) {
	    // fast lane - replace existing text node
	
	    if (textContextSupport) {
	      // 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(document.createTextNode(content));
	  }
	}
	
	/**
	 * Returns true if element is attached to the DOM and visible, false otherwise
	 * @param elem
	 * @returns {boolean}
	 */
	function isVisible(elem) {
	  var next = elem;
	
	  while (polymerUnwrap(next) !== document.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.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 offsetLeft, offsetTop, lastElem, docElem, box;
	
	  docElem = document.documentElement;
	
	  if ((0, _feature.hasCaptionProblem)() && elem.firstChild && elem.firstChild.nodeName === 'CAPTION') {
	    // fixes problem with Firefox ignoring <caption> in TABLE offset (see also export outerHeight)
	    // http://jsperf.com/offset-vs-getboundingclientrect/8
	    box = elem.getBoundingClientRect();
	
	    return {
	      top: box.top + (window.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
	      left: box.left + (window.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
	    };
	  }
	  offsetLeft = elem.offsetLeft;
	  offsetTop = elem.offsetTop;
	  lastElem = elem;
	
	  /* eslint-disable no-cond-assign */
	  while (elem = elem.offsetParent) {
	    // from my observation, document.body always has scrollLeft/scrollTop == 0
	    if (elem === document.body) {
	      break;
	    }
	    offsetLeft += elem.offsetLeft;
	    offsetTop += elem.offsetTop;
	    lastElem = elem;
	  }
	
	  // 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 += window.pageXOffset || docElem.scrollLeft;
	    offsetTop += window.pageYOffset || docElem.scrollTop;
	  }
	
	  return {
	    left: offsetLeft,
	    top: offsetTop
	  };
	}
	
	/**
	 * Returns the document's scrollTop property.
	 *
	 * @returns {Number}
	 */
	function getWindowScrollTop() {
	  var res = window.scrollY;
	
	  if (res === void 0) {
	    // IE8-11
	    res = document.documentElement.scrollTop;
	  }
	
	  return res;
	}
	
	/**
	 * Returns the document's scrollLeft property.
	 *
	 * @returns {Number}
	 */
	function getWindowScrollLeft() {
	  var res = window.scrollX;
	
	  if (res === void 0) {
	    // IE8-11
	    res = document.documentElement.scrollLeft;
	  }
	
	  return res;
	}
	
	/**
	 * Returns the provided element's scrollTop property.
	 *
	 * @param element
	 * @returns {Number}
	 */
	function getScrollTop(element) {
	  if (element === window) {
	    return getWindowScrollTop();
	  }
	  return element.scrollTop;
	}
	
	/**
	 * Returns the provided element's scrollLeft property.
	 *
	 * @param element
	 * @returns {Number}
	 */
	function getScrollLeft(element) {
	  if (element === window) {
	    return getWindowScrollLeft();
	  }
	  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 el = element.parentNode,
	      props = ['auto', 'scroll'],
	      overflow,
	      overflowX,
	      overflowY,
	      computedStyle = '',
	      computedOverflow = '',
	      computedOverflowY = '',
	      computedOverflowX = '';
	
	  while (el && el.style && document.body !== el) {
	    overflow = el.style.overflow;
	    overflowX = el.style.overflowX;
	    overflowY = el.style.overflowY;
	
	    if (overflow == 'scroll' || overflowX == 'scroll' || overflowY == 'scroll') {
	      return el;
	    } else if (window.getComputedStyle) {
	      computedStyle = window.getComputedStyle(el);
	      computedOverflow = computedStyle.getPropertyValue('overflow');
	      computedOverflowY = computedStyle.getPropertyValue('overflow-y');
	      computedOverflowX = computedStyle.getPropertyValue('overflow-x');
	
	      if (computedOverflow === 'scroll' || computedOverflowX === 'scroll' || computedOverflowY === 'scroll') {
	        return el;
	      }
	    }
	
	    // The '+ 1' after the scrollHeight/scrollWidth is to prevent problems with zoomed out Chrome.
	    if (el.clientHeight <= el.scrollHeight + 1 && (props.indexOf(overflowY) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowY) !== -1)) {
	      return el;
	    }
	    if (el.clientWidth <= el.scrollWidth + 1 && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowX) !== -1)) {
	      return el;
	    }
	    el = el.parentNode;
	  }
	
	  return window;
	}
	
	/**
	 * 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 el = base.parentNode;
	
	  while (el && el.style && document.body !== el) {
	    if (el.style.overflow !== 'visible' && el.style.overflow !== '') {
	      return el;
	    } else if (window.getComputedStyle) {
	      var computedStyle = window.getComputedStyle(el);
	
	      if (computedStyle.getPropertyValue('overflow') !== 'visible' && computedStyle.getPropertyValue('overflow') !== '') {
	        return el;
	      }
	    }
	
	    el = el.parentNode;
	  }
	
	  return window;
	}
	
	/**
	 * Returns a style property for the provided element. (Be it an inline or external style).
	 *
	 * @param {HTMLElement} element
	 * @param {String} prop Wanted property
	 * @returns {String|undefined} Element's style property
	 */
	function getStyle(element, prop) {
	  /* eslint-disable */
	  if (!element) {
	    return;
	  } else if (element === window) {
	    if (prop === 'width') {
	      return window.innerWidth + 'px';
	    } else if (prop === 'height') {
	      return window.innerHeight + 'px';
	    }
	
	    return;
	  }
	
	  var styleProp = element.style[prop],
	      computedStyle;
	
	  if (styleProp !== '' && styleProp !== void 0) {
	    return styleProp;
	  } else {
	    computedStyle = getComputedStyle(element);
	
	    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
	 * @returns {IEElementStyle|CssStyle} Elements computed style object
	 */
	function getComputedStyle(element) {
	  return element.currentStyle || document.defaultView.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) {
	  if (window.addEventListener) {
	    element.addEventListener(event, callback, false);
	  } else {
	    element.attachEvent('on' + event, callback);
	  }
	}
	
	function removeEvent(element, event, callback) {
	  if (window.removeEventListener) {
	    element.removeEventListener(event, callback, false);
	  } else {
	    element.detachEvent('on' + event, callback);
	  }
	}
	
	/**
	 * Returns caret position in text input
	 *
	 * @author http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
	 * @return {Number}
	 */
	function getCaretPosition(el) {
	  if (el.selectionStart) {
	    return el.selectionStart;
	  } else if (document.selection) {
	    // IE8
	    el.focus();
	
	    var r = document.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) {
	  if (el.selectionEnd) {
	    return el.selectionEnd;
	  } else if (document.selection) {
	    // IE8
	    var r = document.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.
	 *
	 * @returns {String}
	 */
	function getSelectionText() {
	  var text = '';
	
	  if (window.getSelection) {
	    text = window.getSelection().toString();
	  } else if (document.selection && document.selection.type !== 'Control') {
	    text = document.selection.createRange().text;
	  }
	
	  return text;
	}
	
	/**
	 * 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;
	
	// http://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes
	function walkontableCalculateScrollbarWidth() {
	  var inner = document.createElement('div');
	  inner.style.height = '200px';
	  inner.style.width = '100%';
	
	  var outer = document.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);
	
	  (document.body || document.documentElement).appendChild(outer);
	  var w1 = inner.offsetWidth;
	  outer.style.overflow = 'scroll';
	  var w2 = inner.offsetWidth;
	  if (w1 == w2) {
	    w2 = outer.clientWidth;
	  }
	
	  (document.body || document.documentElement).removeChild(outer);
	
	  return w1 - w2;
	}
	
	/**
	 * Returns the computed width of the native browser scroll bar.
	 *
	 * @return {Number} width
	 */
	function getScrollbarWidth() {
	  if (cachedScrollbarWidth === void 0) {
	    cachedScrollbarWidth = walkontableCalculateScrollbarWidth();
	  }
	
	  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(' + left + ',' + top + ',0)';
	  } else {
	    overlayElem.style.transform = 'translate3d(' + left + ',' + 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;
	}
	
	/***/ }),
	/* 1 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	exports.duckSchema = duckSchema;
	exports.inherit = inherit;
	exports.extend = extend;
	exports.deepExtend = deepExtend;
	exports.deepClone = deepClone;
	exports.clone = clone;
	exports.mixin = mixin;
	exports.isObjectEquals = isObjectEquals;
	exports.isObject = isObject;
	exports.defineGetter = defineGetter;
	exports.objectEach = objectEach;
	exports.getProperty = getProperty;
	exports.deepObjectSize = deepObjectSize;
	exports.createObjectPropListener = createObjectPropListener;
	exports.hasOwnProperty = hasOwnProperty;
	
	var _array = __webpack_require__(2);
	
	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; }
	
	/**
	 * 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 && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && !Array.isArray(value)) {
	        schema[key] = duckSchema(value);
	      } else if (Array.isArray(value)) {
	        if (value.length && _typeof(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] && _typeof(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 ((typeof obj === 'undefined' ? 'undefined' : _typeof(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 = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	    mixins[_key - 1] = arguments[_key];
	  }
	
	  (0, _array.arrayEach)(mixins, function (mixin) {
	    Base.MIXINS.push(mixin.MIXIN_NAME);
	
	    objectEach(mixin, function (value, key) {
	      if (Base.prototype[key] !== void 0) {
	        throw new Error('Mixin conflict. Property \'' + key + '\' already exist and cannot be overwritten.');
	      }
	      if (typeof value === 'function') {
	        Base.prototype[key] = value;
	      } else {
	        var getter = function _getter(propertyName, initialValue) {
	          propertyName = '_' + propertyName;
	
	          var initValue = function initValue(value) {
	            if (Array.isArray(value) || isObject(value)) {
	              value = deepClone(value);
	            }
	
	            return value;
	          };
	
	          return function () {
	            if (this[propertyName] === void 0) {
	              this[propertyName] = initValue(initialValue);
	            }
	
	            return this[propertyName];
	          };
	        };
	        var setter = function _setter(propertyName) {
	          propertyName = '_' + propertyName;
	
	          return function (value) {
	            this[propertyName] = value;
	          };
	        };
	        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 isObjectEquals(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) {
	  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 (name) {
	    result = result[name];
	
	    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++;
	    }
	
	    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 = '_' + propertyToListen;
	  var holder = (_holder = {
	    _touched: false
	  }, _defineProperty(_holder, privateProperty, defaultValue), _defineProperty(_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);
	}
	
	/***/ }),
	/* 2 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	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 i = 0,
	      ilen = arr.length;
	
	  while (i < ilen) {
	    arr[i] = [arr[i]];
	    i++;
	  }
	}
	
	function extendArray(arr, extension) {
	  var i = 0,
	      ilen = extension.length;
	
	  while (i < ilen) {
	    arr.push(extension[i]);
	    i++;
	  }
	}
	
	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,
	      length = array.length;
	
	  if (initFromArray && length) {
	    accumulator = array[++index];
	  }
	  while (++index < length) {
	    accumulator = iteratee(accumulator, array[index], index, array);
	  }
	
	  return accumulator;
	}
	
	/**
	 * 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 = -1,
	      length = array.length,
	      resIndex = -1,
	      result = [];
	
	  while (++index < length) {
	    var value = array[index];
	
	    if (predicate(value, index, array)) {
	      result[++resIndex] = value;
	    }
	  }
	
	  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 = -1,
	      length = array.length,
	      resIndex = -1,
	      result = [];
	
	  while (++index < length) {
	    var value = array[index];
	
	    result[++resIndex] = iteratee(value, index, array);
	  }
	
	  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.
	 * @param {Function} iteratee The function invoked per iteration.
	 * @returns {Array} Returns `array`.
	 */
	function arrayEach(array, iteratee) {
	  var index = -1,
	      length = array.length;
	
	  while (++index < length) {
	    if (iteratee(array[index], index, array) === false) {
	      break;
	    }
	  }
	
	  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;
	}
	
	/***/ }),
	/* 3 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var global = __webpack_require__(11);
	var core = __webpack_require__(44);
	var hide = __webpack_require__(29);
	var redefine = __webpack_require__(28);
	var ctx = __webpack_require__(30);
	var PROTOTYPE = 'prototype';
	
	var $export = function (type, name, source) {
	  var IS_FORCED = type & $export.F;
	  var IS_GLOBAL = type & $export.G;
	  var IS_STATIC = type & $export.S;
	  var IS_PROTO = type & $export.P;
	  var IS_BIND = type & $export.B;
	  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];
	  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});
	  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
	  var key, own, out, exp;
	  if (IS_GLOBAL) source = name;
	  for (key in source) {
	    // contains in native
	    own = !IS_FORCED && target && target[key] !== undefined;
	    // export native or passed
	    out = (own ? target : source)[key];
	    // bind timers to global for call from export context
	    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
	    // extend global
	    if (target) redefine(target, key, out, type & $export.U);
	    // export
	    if (exports[key] != out) hide(exports, key, exp);
	    if (IS_PROTO && expProto[key] != out) expProto[key] = out;
	  }
	};
	global.core = core;
	// type bitmap
	$export.F = 1;   // forced
	$export.G = 2;   // global
	$export.S = 4;   // static
	$export.P = 8;   // proto
	$export.B = 16;  // bind
	$export.W = 32;  // wrap
	$export.U = 64;  // safe
	$export.R = 128; // real proto method for `library`
	module.exports = $export;
	
	
	/***/ }),
	/* 4 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	exports.getListenersCounter = getListenersCounter;
	
	var _element = __webpack_require__(0);
	
	var _object = __webpack_require__(1);
	
	var _feature = __webpack_require__(34);
	
	var _event = __webpack_require__(10);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * 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 = function () {
	  /**
	   * @param {Object} [context=null]
	   * @private
	   */
	  function EventManager() {
	    var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
	
	    _classCallCheck(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.
	   * @returns {Function} Returns function which you can easily call to remove that event
	   */
	
	
	  _createClass(EventManager, [{
	    key: 'addEventListener',
	    value: function addEventListener(element, eventName, callback) {
	      var _this = this;
	
	      var context = this.context;
	
	      function callbackProxy(event) {
	        event = extendEvent(context, event);
	
	        callback.call(this, event);
	      }
	      this.context.eventListeners.push({
	        element: element,
	        event: eventName,
	        callback: callback,
	        callbackProxy: callbackProxy
	      });
	
	      if (window.addEventListener) {
	        element.addEventListener(eventName, callbackProxy, false);
	      } else {
	        element.attachEvent('on' + eventName, callbackProxy);
	      }
	      listenersCounter++;
	
	      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 = void 0;
	
	      while (len--) {
	        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);
	
	          if (tmpEvent.element.removeEventListener) {
	            tmpEvent.element.removeEventListener(tmpEvent.event, tmpEvent.callbackProxy, false);
	          } else {
	            tmpEvent.element.detachEvent('on' + tmpEvent.event, tmpEvent.callbackProxy);
	          }
	          listenersCounter--;
	        }
	      }
	    }
	
	    /**
	     * 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--) {
	        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 options = {
	        bubbles: true,
	        cancelable: eventName !== 'mousemove',
	        view: window,
	        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 (document.createEvent) {
	        event = document.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 || document.body.parentNode);
	      } else {
	        event = document.createEventObject();
	      }
	
	      if (element.dispatchEvent) {
	        element.dispatchEvent(event);
	      } else {
	        element.fireEvent('on' + eventName, event);
	      }
	    }
	  }]);
	
	  return EventManager;
	}();
	
	/**
	 * @param {Object} context
	 * @param {Event} event
	 * @private
	 * @returns {*}
	 */
	
	
	function extendEvent(context, event) {
	  var componentName = 'HOT-TABLE';
	  var isHotTableSpotted = void 0;
	  var fromElement = void 0;
	  var realTarget = void 0;
	  var target = void 0;
	  var len = void 0;
	  var nativeStopImmediatePropagation = void 0;
	
	  event.isTargetWebComponent = false;
	  event.realTarget = event.target;
	
	  nativeStopImmediatePropagation = event.stopImmediatePropagation;
	  event.stopImmediatePropagation = function () {
	    nativeStopImmediatePropagation.apply(this);
	    (0, _event.stopImmediatePropagation)(this);
	  };
	
	  if (!EventManager.isHotTableEnv) {
	    return event;
	  }
	  event = (0, _element.polymerWrap)(event);
	  len = event.path ? event.path.length : 0;
	
	  while (len--) {
	    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;
	}
	
	exports.default = EventManager;
	function getListenersCounter() {
	  return listenersCounter;
	};
	
	/***/ }),
	/* 5 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.getPluginName = exports.getRegistredPluginNames = exports.getPlugin = exports.registerPlugin = undefined;
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _object = __webpack_require__(1);
	
	var _string = __webpack_require__(32);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var registeredPlugins = new WeakMap();
	
	/**
	 * Registers plugin under given name
	 *
	 * @param {String} pluginName
	 * @param {Function} PluginClass
	 */
	/**
	 * Utility to register plugins and common namespace for keeping reference to all plugins classes
	 */
	function registerPlugin(pluginName, PluginClass) {
	  pluginName = (0, _string.toUpperCaseFirst)(pluginName);
	
	  _pluginHooks2.default.getSingleton().add('construct', function () {
	    var holder = void 0;
	
	    if (!registeredPlugins.has(this)) {
	      registeredPlugins.set(this, {});
	    }
	    holder = registeredPlugins.get(this);
	
	    if (!holder[pluginName]) {
	      holder[pluginName] = new PluginClass(this);
	    }
	  });
	  _pluginHooks2.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;
	}
	
	exports.registerPlugin = registerPlugin;
	exports.getPlugin = getPlugin;
	exports.getRegistredPluginNames = getRegistredPluginNames;
	exports.getPluginName = getPluginName;
	
	/***/ }),
	/* 6 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	exports.isNumeric = isNumeric;
	exports.rangeEach = rangeEach;
	exports.rangeEachReverse = rangeEachReverse;
	exports.valueAccordingPercent = valueAccordingPercent;
	/**
	 * 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 = typeof n === 'undefined' ? 'undefined' : _typeof(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} rangeTo The number where finish iterate.
	 * @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;
	}
	
	/***/ }),
	/* 7 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _array = __webpack_require__(2);
	
	var _object = __webpack_require__(1);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @description
	 * Handsontable events are the common interface that function in 2 ways: as __callbacks__ and as __hooks__.
	 *
	 * @example
	 *
	 * ```js
	 * // Using events as callbacks:
	 * ...
	 * var hot1 = new Handsontable(document.getElementById('example1'), {
	 *   afterChange: function(changes, source) {
	 *     $.ajax({
	 *       url: "save.php',
	 *       data: change
	 *     });
	 *   }
	 * });
	 * ...
	 * ```
	 *
	 * ```js
	 * // Using events as plugin hooks:
	 * ...
	 * var hot1 = new Handsontable(document.getElementById('example1'), {
	 *   myPlugin: true
	 * });
	 *
	 * var 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 = [
	/**
	 * Callback fired after resetting a cell's meta.
	 *
	 * @event Hooks#afterCellMetaReset
	 * @since 0.11
	 */
	'afterCellMetaReset',
	
	/**
	 * @description
	 * Callback fired after one or more cells has been changed. Its main use case is to save the input.
	 *
	 * __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 http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
	 */
	'afterChange',
	
	/**
	 * @description
	 * Fired after observing changes.
	 *
	 * @event Hooks#afterChangesObserved
	 */
	'afterChangesObserved',
	
	/**
	 * @description
	 * Fired 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 `contextMenu` option.
	 *
	 * @event Hooks#afterContextMenuDefaultOptions
	 * @param {Array} predefinedItems Array of objects containing information about the pre-defined Context Menu items.
	 */
	'afterContextMenuDefaultOptions',
	
	/**
	 * @description
	 * Fired 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 {Array} menuItems Array of objects containing information about to generated Context Menu items.
	 */
	'beforeContextMenuSetItems',
	
	/**
	 * @description
	 * Fired 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 `contextMenu` option.
	 *
	 * @pro
	 * @event Hooks#afterDropdownMenuDefaultOptions
	 * @param {Array} predefinedItems Array of objects containing information about the pre-defined Context Menu items.
	 */
	'afterDropdownMenuDefaultOptions',
	
	/**
	 * @description
	 * Fired 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.
	 *
	 * @pro
	 * @event Hooks#beforeDropdownMenuSetItems
	 * @param {Array} menuItems Array of objects containing information about to generated Dropdown Menu items.
	 */
	'beforeDropdownMenuSetItems',
	
	/**
	 * @description
	 * Fired after hiding the Context Menu.
	 *
	 * @event Hooks#afterContextMenuHide
	 * @param {Object} context The Context menu instance.
	 */
	'afterContextMenuHide',
	
	/**
	 * @description
	 * Fired after opening the Context Menu.
	 *
	 * @event Hooks#afterContextMenuShow
	 * @param {Object} context The Context Menu instance.
	 */
	'afterContextMenuShow',
	
	/**
	 * @description
	 * Fired after reaching the copy limit while copying data.
	 *
	 * @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',
	
	/**
	 * Callback is fired before a new column was created.
	 *
	 * @since 0.28.0
	 * @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',
	
	/**
	 * Callback is fired after a new column was created.
	 *
	 * @event Hooks#afterCreateCol
	 * @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}).
	 */
	'afterCreateCol',
	
	/**
	 * Callback is fired before a new row was created.
	 *
	 * @since 0.28.0
	 * @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',
	
	/**
	 * Callback is fired after a new row was created.
	 *
	 * @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',
	
	/**
	 * Fired on a `keydown` event on the document body.
	 *
	 * @event Hooks#afterDocumentKeyDown
	 * @param {Event} event A `keydown` event.
	 */
	'afterDocumentKeyDown',
	
	/**
	 * Callback fired after getting the cell settings.
	 *
	 * @event Hooks#afterGetCellMeta
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 * @param {Object} cellProperties Object containing the cell properties.
	 */
	'afterGetCellMeta',
	
	/**
	 * Callback fired after retrieving information about a column header and appending it to the table header.
	 *
	 * @event Hooks#afterGetColHeader
	 * @param {Number} col Visual column index.
	 * @param {Element} TH Header's TH element.
	 */
	'afterGetColHeader',
	
	/**
	 * Callback fired after retrieving information about a column header and appending it to the table header.
	 *
	 * @event Hooks#afterGetRowHeader
	 * @param {Number} row Visual row index.
	 * @param {Element} TH Header's TH element.
	 */
	'afterGetRowHeader',
	
	/**
	 * Callback fired after Handsontable instance is initiated.
	 *
	 * @event Hooks#afterInit
	 */
	'afterInit',
	
	/**
	 * Callback fired after new data is loaded (by `loadData` method) into the data source array.
	 *
	 * @event Hooks#afterLoadData
	 * @param {Boolean} firstTime 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
	 * @since 0.11
	 * @param {Object} event `mousedown` event object.
	 */
	'afterOnCellCornerMouseDown',
	
	/**
	 * Fired after a `dblclick` event is triggered on the cell corner (the drag handle).
	 *
	 * @event Hooks#afterOnCellCornerDblClick
	 * @since 0.30.0
	 * @param {Object} event `dblclick` event object.
	 */
	'afterOnCellCornerDblClick',
	
	/**
	 * Callback fired after clicking on a cell or row/column header.
	 * In case the row/column header was clicked, the index is negative.
	 * For example clicking on the row header of cell (0, 0) results with `afterOnCellMouseDown` called
	 * with coords `{row: 0, col: -1}`.
	 *
	 * @event Hooks#afterOnCellMouseDown
	 * @since 0.11
	 * @param {Object} event `mousedown` event object.
	 * @param {Object} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
	 * @param {Element} TD Cell's TD (or TH) element.
	 */
	'afterOnCellMouseDown',
	
	/**
	 * Callback 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
	 * @since 0.11
	 * @param {Object} event `mouseover` event object.
	 * @param {Object} coords Hovered cell's visual coordinate object.
	 * @param {Element} TD Cell's TD (or TH) element.
	 */
	'afterOnCellMouseOver',
	
	/**
	 * Callback fired after leaving a cell or row/column header with the mouse cursor.
	 *
	 * @event Hooks#afterOnCellMouseOut
	 * @since 0.31.1
	 * @param {Object} event `mouseout` event object.
	 * @param {Object} coords Leaved cell's visual coordinate object.
	 * @param {Element} TD Cell's TD (or TH) element.
	 */
	'afterOnCellMouseOut',
	
	/**
	 * Callback is fired when one or more columns are removed.
	 *
	 * @event Hooks#afterRemoveCol
	 * @param {Number} index Is an visual index of starter column.
	 * @param {Number} amount Is an amount of removed columns.
	 */
	'afterRemoveCol',
	
	/**
	 * Callback is fired when one or more rows are removed.
	 *
	 * @event Hooks#afterRemoveRow
	 * @param {Number} index Is an visual index of starter row.
	 * @param {Number} amount Is an amount of removed rows.
	 */
	'afterRemoveRow',
	
	/**
	 * Callback 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
	 * @since 0.24.2
	 * @param {Element} TD Currently rendered cell's 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.
	 */
	'beforeRenderer',
	
	/**
	 * Fired after finishing rendering the cell (after the renderer finishes).
	 *
	 * @event Hooks#afterRenderer
	 * @since 0.11.0
	 * @param {Element} TD Currently rendered cell's 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.
	 */
	'afterRenderer',
	
	/**
	 * Fired after the horizontal scroll event.
	 *
	 * @event Hooks#afterScrollHorizontally
	 * @since 0.11
	 */
	'afterScrollHorizontally',
	
	/**
	 * Fired after the vertical scroll event.
	 *
	 * @event Hooks#afterScrollVertically
	 * @since 0.11
	 */
	'afterScrollVertically',
	
	/**
	 * Callback fired after one or more cells are selected (e.g. during mouse move).
	 *
	 * @event Hooks#afterSelection
	 * @param {Number} r Selection start visual row index.
	 * @param {Number} c Selection start visual column index.
	 * @param {Number} r2 Selection end visual row index.
	 * @param {Number} c2 Selection end visual column index.
	 * @param {Object} preventScrolling Object with `value` property where its value change will be observed.
	 *    * @example
	 * ```js
	 * handsontable({
	 *   afterSelection: function (r, c, r2, c2, preventScrolling) {
	 *     // setting if prevent scrolling after selection
	 *
	 *     preventScrolling.value = true;
	 *   }
	 * })
	 * ```
	 */
	'afterSelection',
	
	/**
	 * Callback fired after one or more cells are selected. The `p` argument represents the source object property name instead of the column number.
	 *
	 * @event Hooks#afterSelectionByProp
	 * @param {Number} r Selection start visual row index.
	 * @param {String} p Selection start data source object property name.
	 * @param {Number} r2 Selection end visual row index.
	 * @param {String} p2 Selection end data source object property name.
	 * @param {Object} preventScrolling Object with `value` property where its value change will be observed.
	 *    * @example
	 * ```js
	 * handsontable({
	 *   afterSelectionByProp: function (r, c, r2, c2, preventScrolling) {
	 *     // setting if prevent scrolling after selection
	 *
	 *     preventScrolling.value = true;
	 *   }
	 * })
	 * ```
	 */
	'afterSelectionByProp',
	
	/**
	 * Callback fired after one or more cells are selected (e.g. on mouse up).
	 *
	 * @event Hooks#afterSelectionEnd
	 * @param {Number} r Selection start visual row index.
	 * @param {Number} c Selection start visual column index.
	 * @param {Number} r2 Selection end visual row index.
	 * @param {Number} c2 Selection end visual column index.
	 */
	'afterSelectionEnd',
	
	/**
	 * Callback fired after one or more cells are selected (e.g. on mouse up). The `p` argument represents the data source object
	 * property name instead of the column number.
	 *
	 * @event Hooks#afterSelectionEndByProp
	 * @param {Number} r Selection start visual row index.
	 * @param {String} p Selection start data source object property index.
	 * @param {Number} r2 Selection end visual row index.
	 * @param {String} p2 Selection end data source object property index.
	 */
	'afterSelectionEndByProp',
	
	/**
	 * Called after cell meta is changed.
	 *
	 * @event Hooks#afterSetCellMeta
	 * @since 0.11.0
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 * @param {String} key The updated meta key.
	 * @param {*} value The updated meta value.
	 */
	'afterSetCellMeta',
	
	/**
	 * Called after cell meta is removed.
	 *
	 * @event Hooks#afterRemoveCellMeta
	 * @since 0.33.1
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 * @param {String} key The removed meta key.
	 * @param {*} value Value which was under removed key of cell meta.
	 */
	'afterRemoveCellMeta',
	
	/**
	 * Called after cell data was changed.
	 *
	 * @event Hooks#afterSetDataAtCell
	 * @since 0.28.0
	 * @param {Array} changes An array of changes in format `[[row, col, 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',
	
	/**
	 * Called after cell data was changed.
	 *
	 * @event Hooks#afterSetDataAtRowProp
	 * @since 0.28.0
	 * @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} settings 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
	 * @since 0.9.5
	 * @param {Boolean} isValid `true` if valid, `false` if not.
	 * @param {*} value The value in question.
	 * @param {Number} row 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}).
	 */
	'afterValidate',
	
	/**
	 * Fired before populating the data in the autofill feature.
	 *
	 * @event Hooks#beforeAutofill
	 * @param {Object} start Object containing information about first filled cell: `{row: 2, col: 0}`.
	 * @param {Object} 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 stateBefore
	 * @param range
	 * @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`
	 * for horizontal alignment,
	 *
	 *
	 * * `htTop`,
	 * * `htMiddle`,
	 * * `htBottom`
	 * for vertical alignment.
	 */
	'beforeCellAlignment',
	
	/**
	 * Callback fired before one or more cells is changed. Its main purpose is to alter changes silently before input.
	 *
	 * @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(document.getElementById('example'), {
	 *   beforeChange: function(changes, source) {
	 *     // [[row, prop, oldVal, newVal], ...]
	 *     changes[0] = null;
	 *   }
	 * });
	 * ...
	 *
	 * // To alter a single change, overwrite the desired value to changes[i][3].
	 * ...
	 * new Handsontable(document.getElementById('example'), {
	 *   beforeChange: function(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(document.getElementById('example'), {
	 *   beforeChange: function(changes, source) {
	 *     // [[row, prop, oldVal, newVal], ...]
	 *     return false;
	 *   }
	 * });
	 * ...
	 * ```
	 */
	'beforeChange',
	
	/**
	 * Fired right before rendering the changes.
	 *
	 * @event Hooks#beforeChangeRender
	 * @since 0.11
	 * @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',
	
	/**
	 * Callback fired before getting cell settings.
	 *
	 * @event Hooks#beforeGetCellMeta
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 * @param {Object} cellProperties Object containing the cell's properties.
	 */
	'beforeGetCellMeta',
	
	/**
	 * Called before cell meta is removed.
	 *
	 * @event Hooks#beforeRemoveCellMeta
	 * @since 0.33.1
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 * @param {String} key The removed meta key.
	 * @param {*} value Value which is under removed key of cell meta.
	 */
	'beforeRemoveCellMeta',
	
	/**
	 * @description
	 * Callback fired before Handsontable instance is initiated.
	 *
	 * @event Hooks#beforeInit
	 */
	'beforeInit',
	
	/**
	 * Callback fired before Walkontable instance is initiated.
	 *
	 * @since 0.11
	 * @event Hooks#beforeInitWalkontable
	 * @param {Object} walkontableConfig Walkontable configuration object.
	 */
	'beforeInitWalkontable',
	
	/**
	 * Callback fired before keydown event is handled. It can be used to overwrite default key bindings.
	 * Caution - in your `beforeKeyDown` handler you need to call `event.stopImmediatePropagation()` to prevent default key behavior.
	 *
	 * @event Hooks#beforeKeyDown
	 * @since 0.9.0
	 * @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 {Element} TD TD element.
	 */
	'beforeOnCellMouseDown',
	
	/**
	 * 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 {Element} TD TD element.
	 * @param {Object} blockCalculations Contain keys 'row' and 'column' with boolean value.
	 */
	'beforeOnCellMouseOver',
	
	/**
	 * Fired after the user moved cursor out from a cell, but before all the calculations related with it.
	 *
	 * @event Hooks#beforeOnCellMouseOut
	 * @since 0.31.1
	 * @param {Event} event The `mouseout` event object.
	 * @param {WalkontableCellCoords} coords WalkontableCellCoords object containing the visual coordinates of the leaved cell.
	 * @param {Element} TD TD element.
	 */
	'beforeOnCellMouseOut',
	
	/**
	 * Callback is fired when 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 {Array} [visualCols] Consists of visual indexes of processed columns.
	 */
	'beforeRemoveCol',
	
	/**
	 * Callback is 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 {Array} [visualRows] Consists of visual indexes of processed rows.
	 */
	'beforeRemoveRow',
	
	/**
	 * Callback fired before 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',
	
	/**
	 * Callback fired before setting range is started.
	 *
	 * @event Hooks#beforeSetRangeStart
	 * @param {Array} coords CellCoords array.
	 */
	'beforeSetRangeStart',
	
	/**
	 * Callback fired before setting range is ended.
	 *
	 * @event Hooks#beforeSetRangeEnd
	 * @param {Array} coords CellCoords array.
	 */
	'beforeSetRangeEnd',
	
	/**
	 * Fired before the logic of handling a touch scroll, when user started scrolling on a touch-enabled device.
	 *
	 * @event Hooks#beforeTouchScroll
	 */
	'beforeTouchScroll',
	
	/**
	 * @description
	 * A plugin hook executed before validator function, 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.
	 *
	 * __Notice:__ this will not affect values of changes. This will change value ONLY for validation!
	 *
	 * @event Hooks#beforeValidate
	 * @since 0.9.5
	 * @param {*} value Value of the cell.
	 * @param {Number} row 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',
	
	/**
	 * Callback fired before cell value is rendered into the DOM (through renderer function).
	 *
	 * @event Hooks#beforeValueRender
	 * @since 0.29.0
	 * @param {*} value Cell value to render.
	 */
	'beforeValueRender',
	
	/**
	 * Callback fired after Handsontable instance is constructed (via `new` operator).
	 *
	 * @event Hooks#construct
	 * @since 0.16.1
	 */
	'construct',
	
	/**
	 * Callback fired after Handsontable instance is initiated but before table is rendered.
	 *
	 * @event Hooks#init
	 * @since 0.16.1
	 */
	'init',
	
	/**
	 * Fired when a column index is about to be modified by a callback function.
	 *
	 * @event Hooks#modifyCol
	 * @since 0.11
	 * @param {Number} col Visual column index.
	 */
	'modifyCol',
	
	/**
	 * Fired when a column index is about to be de-modified by a callback function.
	 *
	 * @event Hooks#unmodifyCol
	 * @since 0.23.0
	 * @param {Number} col Physical column index.
	 */
	'unmodifyCol',
	
	/**
	 * Fired when a physical row index is about to be de-modified by a callback function.
	 *
	 * @event Hooks#unmodifyRow
	 * @since 0.26.2
	 * @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
	 * @since 0.20.0
	 * @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
	 * @since 0.11
	 * @param {Number} width Current column width.
	 * @param {Number} col Column index.
	 */
	'modifyColWidth',
	
	/**
	 * Fired when a row index is about to be modified by a callback function.
	 *
	 * @event Hooks#modifyRow
	 * @since 0.11
	 * @param {Number} row Row index.
	 */
	'modifyRow',
	
	/**
	 * Fired when a row header index is about to be modified by a callback function.
	 *
	 * @event Hooks#modifyRowHeader
	 * @since 0.20.0
	 * @param {Number} row Row header index.
	 */
	'modifyRowHeader',
	
	/**
	 * Fired when a row height is about to be modified by a callback function.
	 *
	 * @event Hooks#modifyRowHeight
	 * @since 0.11.0
	 * @param {Number} height Row height.
	 * @param {Number} row Row index.
	 */
	'modifyRowHeight',
	
	/**
	 * Fired when a data was retrieved or modified.
	 *
	 * @event Hooks#modifyData
	 * @since 0.28.0
	 * @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
	 * @since 0.28.0
	 * @param {Number} row Physical row index.
	 */
	'modifyRowData',
	
	/**
	 * Fired after loading data using the Persistent State plugin.
	 *
	 * @event Hooks#persistentStateLoad
	 * @param {String} key Key string.
	 * @param {Object} valuePlaceholder Object containing the loaded data.
	 */
	'persistentStateLoad',
	
	/**
	 * Fired after resetting data using the Persistent State plugin.
	 *
	 * @event Hooks#persistentStateReset
	 * @param {String} key Key string.
	 */
	'persistentStateReset',
	
	/**
	 * Fired after resetting data using the Persistent State plugin.
	 *
	 * @event Hooks#persistentStateSave
	 * @param {String} key Key string.
	 * @param {Mixed} value Value to save.
	 */
	'persistentStateSave',
	
	/**
	 * Fired before sorting the column. If you return `false` value then sorting will be not applied by
	 * Handsontable (useful for server-side sorting).
	 *
	 * @event Hooks#beforeColumnSort
	 * @param {Number} column Sorted visual column index.
	 * @param {Boolean} order Soring order where:
	 *  * `true` means ascending order,
	 *  * `false` means descending order,
	 *  * `undefined` means original order.
	 */
	'beforeColumnSort',
	
	/**
	 * Fired after sorting the column.
	 *
	 * @event Hooks#afterColumnSort
	 * @param {Number} column Sorted visual column index.
	 * @param {Boolean} order Soring order where:
	 *  * `true` means ascending order
	 *  * `false` means descending order
	 *  * `undefined` means original order
	 */
	'afterColumnSort',
	
	/**
	 * @description
	 * Fired after setting range of autofill.
	 * Both arguments are provided in the following format:
	 * ```js
	 * [startRow, startColumn, endRow, endColumn]
	 * ```
	 *
	 * @event Hooks#modifyAutofillRange
	 * @param {Array} startArea Array of visual coordinates of the starting point for the drag-down operation.
	 * @param {Array} entireArea Array of visual coordinates of the entire area of the drag-down operation.
	 */
	'modifyAutofillRange',
	
	/**
	 * Fired to allow modifying the copyable range with a callback function.
	 *
	 * @since 0.19.0
	 * @event Hooks#modifyCopyableRange
	 * @param {Array} copyableRanges Array of objects defining copyable cells.
	 */
	'modifyCopyableRange',
	
	/**
	 * Called before copying the values into clipboard and before clearing values of the selected cells.
	 *
	 * @event Hooks#beforeCut
	 * @since 0.31.1
	 * @param {Array} data An array of arrays which contains data to cut.
	 * @param {Array} 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 cancelled.
	 *
	 * @example
	 * ```js
	 * // To disregard a single row, remove it from array using data.splice(i, 1).
	 * ...
	 * new Handsontable(document.getElementById('example'), {
	 *   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 cutting out, return false from the callback.
	 * ...
	 * new Handsontable(document.getElementById('example'), {
	 *   beforeCut: function(data, coords) {
	 *     return false;
	 *   }
	 * });
	 * ...
	 * ```
	 */
	'beforeCut',
	
	/**
	 * Fired after data are cutted out from the table.
	 *
	 * @event Hooks#afterCut
	 * @since 0.31.1
	 * @param {Array} data An array of arrays which contains the cutted out data.
	 * @param {Array} 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
	 * @since 0.31.1
	 * @param {Array} data An array of arrays which contains data to copied.
	 * @param {Array} 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 cancelled.
	 *
	 * @example
	 * ```js
	 * // To disregard a single row, remove it from array using data.splice(i, 1).
	 * ...
	 * new Handsontable(document.getElementById('example'), {
	 *   beforeCopy: 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 copying, return false from the callback.
	 * ...
	 * new Handsontable(document.getElementById('example'), {
	 *   beforeCopy: function(data, coords) {
	 *     return false;
	 *   }
	 * });
	 * ...
	 * ```
	 */
	'beforeCopy',
	
	/**
	 * Fired after data are pasted into table.
	 *
	 * @event Hooks#afterCopy
	 * @since 0.31.1
	 * @param {Array} data An array of arrays which contains the copied data.
	 * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
	 *                       which was copied.
	 */
	'afterCopy',
	
	/**
	 * Fired before values are pasted into table.
	 *
	 * @event Hooks#beforePaste
	 * @since 0.31.1
	 * @param {Array} data An array of arrays which contains data to paste.
	 * @param {Array} 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 cancelled.
	 *
	 * @example
	 * ```js
	 * // To disregard a single row, remove it from array using data.splice(i, 1).
	 * ...
	 * new Handsontable(document.getElementById('example'), {
	 *   beforePaste: 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 pasting, return false from the callback.
	 * ...
	 * new Handsontable(document.getElementById('example'), {
	 *   beforePaste: function(data, coords) {
	 *     return false;
	 *   }
	 * });
	 * ...
	 * ```
	 */
	'beforePaste',
	
	/**
	 * Fired after values are pasted into table.
	 *
	 * @event Hooks#afterPaste
	 * @since 0.31.1
	 * @param {Array} data An array of arrays which contains the pasted data.
	 * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
	 *                       that correspond to the previously selected area.
	 */
	'afterPaste',
	
	/**
	 * Fired before change order of the visual indexes.
	 *
	 * @event Hooks#beforeColumnMove
	 * @param {Array} columns Array of visual column indexes to be moved.
	 * @param {Number} target Visual column index being a target for moved columns.
	 */
	'beforeColumnMove',
	
	/**
	 * Fired after change order of the visual indexes.
	 *
	 * @event Hooks#afterColumnMove
	 * @param {Array} columns Array of visual column indexes that were moved.
	 * @param {Number} target Visual column index being a target for moved columns.
	 */
	'afterColumnMove',
	
	/**
	 * Fired before change order of the visual indexes.
	 *
	 * @event Hooks#beforeRowMove
	 * @param {Array} rows Array of visual row indexes to be moved.
	 * @param {Number} target Visual row index being a target for moved rows.
	 */
	'beforeRowMove',
	
	/**
	 * Fired after change order of the visual indexes.
	 *
	 * @event Hooks#afterRowMove
	 * @param {Array} rows Array of visual row indexes that were moved.
	 * @param {Number} target Visual row index being a target for moved rows.
	 */
	'afterRowMove',
	
	/**
	 * Fired before rendering the table with modified column sizes.
	 *
	 * @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 after rendering the table with modified column sizes.
	 *
	 * @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 before rendering the table with modified row sizes.
	 *
	 * @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 after rendering the table with modified row sizes.
	 *
	 * @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 {Array} array Array of the column header renderers.
	 */
	'afterGetColumnHeaderRenderers',
	
	/**
	 * Fired after getting the row header renderers.
	 *
	 * @event Hooks#afterGetRowHeaderRenderers
	 * @param {Array} array 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 before applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}.
	 *
	 * @pro
	 * @event Hooks#beforeFilter
	 * @param {Array} conditionsStack An array of objects with added formulas.
	 * @returns {Boolean} If hook returns `false` value then filtering won't be applied on the UI side (server-side filtering).
	 */
	'beforeFilter',
	
	/**
	 * Fired after applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}.
	 *
	 * @pro
	 * @event Hooks#afterFilter
	 * @param {Array} conditionsStack An array of objects with added formulas.
	 */
	'afterFilter',
	
	/**
	 * Used to modify the column header height.
	 *
	 * @event Hooks#modifyColumnHeaderHeight
	 * @since 0.25.0
	 * @param {Number} col Visual column index.
	 */
	'modifyColumnHeaderHeight',
	
	/**
	 * Fired before the undo action. Contains information about the action that is being undone.
	 *
	 * @event Hooks#beforeUndo
	 * @since 0.26.2
	 * @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 after the undo action. Contains information about the action that is being undone.
	 *
	 * @event Hooks#afterUndo
	 * @since 0.26.2
	 * @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 before the redo action. Contains information about the action that is being redone.
	 *
	 * @event Hooks#beforeRedo
	 * @since 0.26.2
	 * @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 after the redo action. Contains information about the action that is being redone.
	 *
	 * @event Hooks#afterRedo
	 * @since 0.26.2
	 * @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',
	
	/**
	 * Used to modify 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 Array of arrays. 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 when saving/loading the manual row heights state.
	 *
	 * @event Hooks#manualRowHeights
	 * @param {Array} state The current manual row heights state.
	 */
	'manualRowHeights',
	
	/**
	 * 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 after trimming rows in the TrimRows plugin.
	 *
	 * @pro
	 * @event Hooks#afterTrimRow
	 * @param {Array} rows Physical indexes of trimmed rows.
	 */
	'afterTrimRow',
	
	/**
	 * Fired after untrimming rows in the TrimRows plugin.
	 *
	 * @pro
	 * @event Hooks#afterUntrimRow
	 * @param {Array} rows Physical indexes of untrimmed rows.
	 */
	'afterUntrimRow',
	
	/**
	 * Fired after opening the dropdown menu.
	 *
	 * @pro
	 * @event Hooks#afterDropdownMenuShow
	 * @param {DropdownMenu} instance The DropdownMenu instance.
	 */
	'afterDropdownMenuShow',
	
	/**
	 * Fired after hiding the dropdown menu.
	 *
	 * @pro
	 * @event Hooks#afterDropdownMenuHide
	 * @param {DropdownMenu} instance The DropdownMenu instance.
	 */
	'afterDropdownMenuHide',
	
	/**
	 * Used to check whether the provided row index is hidden.
	 *
	 * @pro
	 * @event Hooks#hiddenRow
	 * @param {Number} row The visual row index in question.
	 */
	'hiddenRow',
	
	/**
	 * Used to check whether the provided column index is hidden.
	 *
	 * @pro
	 * @event Hooks#hiddenColumn
	 * @param {Number} column The visual column index in question.
	 */
	'hiddenColumn',
	
	/**
	 * Fired before adding a children to the NestedRows structure.
	 *
	 * @pro
	 * @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 after adding a children to the NestedRows structure.
	 *
	 * @pro
	 * @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 before detaching a child from its parent in the NestedRows plugin.
	 *
	 * @pro
	 * @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 after detaching a child from its parent in the NestedRows plugin.
	 *
	 * @pro
	 * @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 Row index of the edited cell.
	 * @param {Number} column Column index of the edited cell.
	 */
	'afterBeginEditing',
	
	/**
	 * Fired after the listening is turned on.
	 *
	 * @event Hooks#afterListen
	 * @since 0.34.5
	 */
	'afterListen',
	
	/**
	 * Fired after the listening is turned off.
	 *
	 * @event Hooks#afterUnlisten
	 * @since 0.34.5
	 */
	'afterUnlisten'];
	
	var Hooks = function () {
	  _createClass(Hooks, null, [{
	    key: 'getSingleton',
	    value: function getSingleton() {
	      return globalSingleton;
	    }
	
	    /**
	     *
	     */
	
	  }]);
	
	  function Hooks() {
	    _classCallCheck(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: [],
	   * ...
	   * }
	   * ```
	   */
	
	
	  _createClass(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 index = -1;
	        var length = globalHandlers ? globalHandlers.length : 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) {
	              /* 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) {
	              p1 = res;
	            }
	            if (globalHandlers[index] && globalHandlers[index].runOnce) {
	              this.remove(key, globalHandlers[index]);
	            }
	          }
	        }
	      }
	      {
	        var localHandlers = this.getBucket(context)[key];
	        var _index = -1;
	        var _length = localHandlers ? localHandlers.length : 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) {
	              /* 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) {
	              p1 = _res;
	            }
	            if (localHandlers[_index] && localHandlers[_index].runOnce) {
	              this.remove(key, localHandlers[_index], context);
	            }
	          }
	        }
	      }
	
	      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();
	
	exports.default = Hooks;
	
	/***/ }),
	/* 8 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.getRegisteredRenderers = exports.getRegisteredRendererNames = exports.hasRenderer = exports.getRenderer = exports.registerRenderer = undefined;
	
	var _staticRegister2 = __webpack_require__(63);
	
	var _staticRegister3 = _interopRequireDefault(_staticRegister2);
	
	var _cellDecorator = __webpack_require__(220);
	
	var _cellDecorator2 = _interopRequireDefault(_cellDecorator);
	
	var _autocompleteRenderer = __webpack_require__(221);
	
	var _autocompleteRenderer2 = _interopRequireDefault(_autocompleteRenderer);
	
	var _checkboxRenderer = __webpack_require__(222);
	
	var _checkboxRenderer2 = _interopRequireDefault(_checkboxRenderer);
	
	var _htmlRenderer = __webpack_require__(223);
	
	var _htmlRenderer2 = _interopRequireDefault(_htmlRenderer);
	
	var _numericRenderer = __webpack_require__(224);
	
	var _numericRenderer2 = _interopRequireDefault(_numericRenderer);
	
	var _passwordRenderer = __webpack_require__(225);
	
	var _passwordRenderer2 = _interopRequireDefault(_passwordRenderer);
	
	var _textRenderer = __webpack_require__(226);
	
	var _textRenderer2 = _interopRequireDefault(_textRenderer);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var _staticRegister = (0, _staticRegister3.default)('renderers'),
	    register = _staticRegister.register,
	    getItem = _staticRegister.getItem,
	    hasItem = _staticRegister.hasItem,
	    getNames = _staticRegister.getNames,
	    getValues = _staticRegister.getValues;
	
	register('base', _cellDecorator2.default);
	register('autocomplete', _autocompleteRenderer2.default);
	register('checkbox', _checkboxRenderer2.default);
	register('html', _htmlRenderer2.default);
	register('numeric', _numericRenderer2.default);
	register('password', _passwordRenderer2.default);
	register('text', _textRenderer2.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 "' + name + '" name');
	  }
	
	  return getItem(name);
	}
	
	exports.registerRenderer = register;
	exports.getRenderer = _getItem;
	exports.hasRenderer = hasItem;
	exports.getRegisteredRendererNames = getNames;
	exports.getRegisteredRenderers = getValues;
	
	/***/ }),
	/* 9 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var store = __webpack_require__(69)('wks');
	var uid = __webpack_require__(42);
	var Symbol = __webpack_require__(11).Symbol;
	var USE_SYMBOL = typeof Symbol == 'function';
	
	var $exports = module.exports = function (name) {
	  return store[name] || (store[name] =
	    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
	};
	
	$exports.store = store;
	
	
	/***/ }),
	/* 10 */
	/***/ (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__(0);
	
	/**
	 * 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;
	  }
	
	  return event.clientX + (0, _element.getWindowScrollLeft)();
	}
	
	/**
	 * 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;
	  }
	
	  return event.clientY + (0, _element.getWindowScrollTop)();
	}
	
	/**
	 * 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;
	}
	
	/***/ }),
	/* 11 */
	/***/ (function(module, exports) {
	
	// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
	var global = module.exports = typeof window != 'undefined' && window.Math == Math
	  ? window : typeof self != 'undefined' && self.Math == Math ? self
	  // eslint-disable-next-line no-new-func
	  : Function('return this')();
	if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
	
	
	/***/ }),
	/* 12 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.Viewport = exports.TableRenderer = exports.Table = exports.Settings = exports.Selection = exports.Scroll = exports.Overlays = exports.Event = exports.Core = exports.default = exports.Border = exports.TopLeftCornerOverlay = exports.TopOverlay = exports.LeftOverlay = exports.DebugOverlay = exports.RowFilter = exports.ColumnFilter = exports.CellRange = exports.CellCoords = exports.ViewportRowsCalculator = exports.ViewportColumnsCalculator = undefined;
	
	__webpack_require__(89);
	
	__webpack_require__(103);
	
	__webpack_require__(104);
	
	__webpack_require__(108);
	
	__webpack_require__(109);
	
	__webpack_require__(111);
	
	__webpack_require__(113);
	
	__webpack_require__(114);
	
	__webpack_require__(115);
	
	__webpack_require__(116);
	
	__webpack_require__(117);
	
	__webpack_require__(118);
	
	__webpack_require__(119);
	
	__webpack_require__(120);
	
	__webpack_require__(122);
	
	__webpack_require__(124);
	
	__webpack_require__(125);
	
	__webpack_require__(126);
	
	__webpack_require__(127);
	
	__webpack_require__(128);
	
	__webpack_require__(129);
	
	__webpack_require__(130);
	
	__webpack_require__(131);
	
	__webpack_require__(132);
	
	__webpack_require__(133);
	
	__webpack_require__(134);
	
	__webpack_require__(135);
	
	__webpack_require__(136);
	
	__webpack_require__(78);
	
	__webpack_require__(137);
	
	__webpack_require__(138);
	
	__webpack_require__(140);
	
	__webpack_require__(141);
	
	__webpack_require__(142);
	
	__webpack_require__(143);
	
	__webpack_require__(144);
	
	__webpack_require__(145);
	
	__webpack_require__(146);
	
	__webpack_require__(148);
	
	__webpack_require__(149);
	
	__webpack_require__(150);
	
	__webpack_require__(152);
	
	__webpack_require__(153);
	
	__webpack_require__(154);
	
	var _viewportColumns = __webpack_require__(155);
	
	var _viewportColumns2 = _interopRequireDefault(_viewportColumns);
	
	var _viewportRows = __webpack_require__(156);
	
	var _viewportRows2 = _interopRequireDefault(_viewportRows);
	
	var _coords = __webpack_require__(49);
	
	var _coords2 = _interopRequireDefault(_coords);
	
	var _range = __webpack_require__(79);
	
	var _range2 = _interopRequireDefault(_range);
	
	var _column = __webpack_require__(157);
	
	var _column2 = _interopRequireDefault(_column);
	
	var _row = __webpack_require__(158);
	
	var _row2 = _interopRequireDefault(_row);
	
	var _debug = __webpack_require__(204);
	
	var _debug2 = _interopRequireDefault(_debug);
	
	var _left = __webpack_require__(206);
	
	var _left2 = _interopRequireDefault(_left);
	
	var _top = __webpack_require__(207);
	
	var _top2 = _interopRequireDefault(_top);
	
	var _topLeftCorner = __webpack_require__(208);
	
	var _topLeftCorner2 = _interopRequireDefault(_topLeftCorner);
	
	var _border = __webpack_require__(167);
	
	var _border2 = _interopRequireDefault(_border);
	
	var _core = __webpack_require__(159);
	
	var _core2 = _interopRequireDefault(_core);
	
	var _event = __webpack_require__(160);
	
	var _event2 = _interopRequireDefault(_event);
	
	var _overlays = __webpack_require__(161);
	
	var _overlays2 = _interopRequireDefault(_overlays);
	
	var _scroll = __webpack_require__(162);
	
	var _scroll2 = _interopRequireDefault(_scroll);
	
	var _selection = __webpack_require__(209);
	
	var _selection2 = _interopRequireDefault(_selection);
	
	var _settings = __webpack_require__(163);
	
	var _settings2 = _interopRequireDefault(_settings);
	
	var _table = __webpack_require__(164);
	
	var _table2 = _interopRequireDefault(_table);
	
	var _tableRenderer = __webpack_require__(165);
	
	var _tableRenderer2 = _interopRequireDefault(_tableRenderer);
	
	var _viewport = __webpack_require__(166);
	
	var _viewport2 = _interopRequireDefault(_viewport);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	exports.ViewportColumnsCalculator = _viewportColumns2.default;
	exports.ViewportRowsCalculator = _viewportRows2.default;
	exports.CellCoords = _coords2.default;
	exports.CellRange = _range2.default;
	exports.ColumnFilter = _column2.default;
	exports.RowFilter = _row2.default;
	exports.DebugOverlay = _debug2.default;
	exports.LeftOverlay = _left2.default;
	exports.TopOverlay = _top2.default;
	exports.TopLeftCornerOverlay = _topLeftCorner2.default;
	exports.Border = _border2.default;
	exports.default = _core2.default;
	exports.Core = _core2.default;
	exports.Event = _event2.default;
	exports.Overlays = _overlays2.default;
	exports.Scroll = _scroll2.default;
	exports.Selection = _selection2.default;
	exports.Settings = _settings2.default;
	exports.Table = _table2.default;
	exports.TableRenderer = _tableRenderer2.default;
	exports.Viewport = _viewport2.default;
	
	/***/ }),
	/* 13 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _object = __webpack_require__(1);
	
	var _array = __webpack_require__(2);
	
	var _recordTranslator = __webpack_require__(172);
	
	var _plugins = __webpack_require__(5);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	var privatePool = new WeakMap();
	var initializedPlugins = null;
	
	/**
	 * @private
	 */
	
	var BasePlugin = function () {
	  /**
	   * @param {Object} hotInstance Handsontable instance.
	   */
	  function BasePlugin(hotInstance) {
	    var _this = this;
	
	    _classCallCheck(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 () {
	      return _this.onUpdateSettings();
	    });
	    this.hot.addHook('beforeInit', function () {
	      return _this.init();
	    });
	  }
	
	  _createClass(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;
	}();
	
	exports.default = BasePlugin;
	
	/***/ }),
	/* 14 */
	/***/ (function(module, exports) {
	
	module.exports = function (it) {
	  return typeof it === 'object' ? it !== null : typeof it === 'function';
	};
	
	
	/***/ }),
	/* 15 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.getRegisteredEditors = exports.getRegisteredEditorNames = exports.hasEditor = exports.getEditorInstance = exports.getEditor = exports.registerEditor = undefined;
	exports.RegisteredEditor = RegisteredEditor;
	exports._getEditorInstance = _getEditorInstance;
	
	var _staticRegister2 = __webpack_require__(63);
	
	var _staticRegister3 = _interopRequireDefault(_staticRegister2);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _baseEditor = __webpack_require__(41);
	
	var _baseEditor2 = _interopRequireDefault(_baseEditor);
	
	var _autocompleteEditor = __webpack_require__(168);
	
	var _autocompleteEditor2 = _interopRequireDefault(_autocompleteEditor);
	
	var _checkboxEditor = __webpack_require__(211);
	
	var _checkboxEditor2 = _interopRequireDefault(_checkboxEditor);
	
	var _dateEditor = __webpack_require__(212);
	
	var _dateEditor2 = _interopRequireDefault(_dateEditor);
	
	var _dropdownEditor = __webpack_require__(215);
	
	var _dropdownEditor2 = _interopRequireDefault(_dropdownEditor);
	
	var _handsontableEditor = __webpack_require__(169);
	
	var _handsontableEditor2 = _interopRequireDefault(_handsontableEditor);
	
	var _mobileTextEditor = __webpack_require__(216);
	
	var _mobileTextEditor2 = _interopRequireDefault(_mobileTextEditor);
	
	var _numericEditor = __webpack_require__(217);
	
	var _numericEditor2 = _interopRequireDefault(_numericEditor);
	
	var _passwordEditor = __webpack_require__(218);
	
	var _passwordEditor2 = _interopRequireDefault(_passwordEditor);
	
	var _selectEditor = __webpack_require__(219);
	
	var _selectEditor2 = _interopRequireDefault(_selectEditor);
	
	var _textEditor = __webpack_require__(51);
	
	var _textEditor2 = _interopRequireDefault(_textEditor);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var registeredEditorClasses = new WeakMap(); /**
	                                              * Utility to register editors and common namespace for keeping reference to all editor classes
	                                              */
	
	var _staticRegister = (0, _staticRegister3.default)('editors'),
	    register = _staticRegister.register,
	    getItem = _staticRegister.getItem,
	    hasItem = _staticRegister.hasItem,
	    getNames = _staticRegister.getNames,
	    getValues = _staticRegister.getValues;
	
	_register('base', _baseEditor2.default);
	_register('autocomplete', _autocompleteEditor2.default);
	_register('checkbox', _checkboxEditor2.default);
	_register('date', _dateEditor2.default);
	_register('dropdown', _dropdownEditor2.default);
	_register('handsontable', _handsontableEditor2.default);
	_register('mobile', _mobileTextEditor2.default);
	_register('numeric', _numericEditor2.default);
	_register('password', _passwordEditor2.default);
	_register('select', _selectEditor2.default);
	_register('text', _textEditor2.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];
	  };
	
	  _pluginHooks2.default.getSingleton().add('afterDestroy', function () {
	    instances = {};
	  });
	}
	
	/**
	 * 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 = void 0;
	
	  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 "' + 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 "' + 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);
	}
	
	exports.registerEditor = _register;
	exports.getEditor = _getItem;
	exports.getEditorInstance = _getEditorInstance;
	exports.hasEditor = hasItem;
	exports.getRegisteredEditorNames = getNames;
	exports.getRegisteredEditors = getValues;
	
	/***/ }),
	/* 16 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var isObject = __webpack_require__(14);
	module.exports = function (it) {
	  if (!isObject(it)) throw TypeError(it + ' is not an object!');
	  return it;
	};
	
	
	/***/ }),
	/* 17 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var anObject = __webpack_require__(16);
	var IE8_DOM_DEFINE = __webpack_require__(91);
	var toPrimitive = __webpack_require__(65);
	var dP = Object.defineProperty;
	
	exports.f = __webpack_require__(20) ? Object.defineProperty : function defineProperty(O, P, Attributes) {
	  anObject(O);
	  P = toPrimitive(P, true);
	  anObject(Attributes);
	  if (IE8_DOM_DEFINE) try {
	    return dP(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;
	};
	
	
	/***/ }),
	/* 18 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY_CODES = undefined;
	exports.isPrintableChar = isPrintableChar;
	exports.isMetaKey = isMetaKey;
	exports.isCtrlKey = isCtrlKey;
	exports.isKey = isKey;
	
	var _array = __webpack_require__(2);
	
	var KEY_CODES = exports.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_LEFT: 91,
	  COMMAND_LEFT: 17,
	  COMMAND_RIGHT: 93,
	  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,
	  X: 88,
	  C: 67,
	  V: 86
	};
	
	/**
	 * Returns true if keyCode represents a printable character.
	 *
	 * @param {Number} keyCode
	 * @returns {Boolean}
	 */
	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;
	}
	
	/**
	 * @param {Number} keyCode
	 * @returns {Boolean}
	 */
	function isCtrlKey(keyCode) {
	  return [KEY_CODES.CONTROL_LEFT, 224, KEY_CODES.COMMAND_LEFT, KEY_CODES.COMMAND_RIGHT].indexOf(keyCode) !== -1;
	}
	
	/**
	 * @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;
	}
	
	/***/ }),
	/* 19 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	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__(2);
	
	var _element = __webpack_require__(0);
	
	var _separator = __webpack_require__(86);
	
	function normalizeSelection(selRange) {
	  return {
	    start: selRange.getTopLeftCorner(),
	    end: selRange.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;
	  }
	  className = className.replace('htTop', '').replace('htMiddle', '').replace('htBottom', '').replace('  ', '');
	
	  className += ' ' + alignment;
	
	  return className;
	}
	
	function prepareHorizontalAlignClass(className, alignment) {
	  if (className.indexOf(alignment) != -1) {
	    return className;
	  }
	  className = className.replace('htLeft', '').replace('htCenter', '').replace('htRight', '').replace('htJustify', '').replace('  ', '');
	
	  className += ' ' + alignment;
	
	  return className;
	}
	
	function getAlignmentClasses(range, callback) {
	  var classes = {};
	
	  for (var row = range.from.row; row <= range.to.row; row++) {
	    for (var col = range.from.col; col <= range.to.col; col++) {
	      if (!classes[row]) {
	        classes[row] = [];
	      }
	      classes[row][col] = callback(row, col);
	    }
	  }
	
	  return classes;
	}
	
	function align(range, type, alignment, cellDescriptor, propertySetter) {
	  if (range.from.row == range.to.row && range.from.col == range.to.col) {
	    applyAlignClassName(range.from.row, range.from.col, type, alignment, cellDescriptor, propertySetter);
	  } else {
	    for (var row = range.from.row; row <= range.to.row; row++) {
	      for (var col = range.from.col; col <= range.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(range, comparator) {
	  var result = false;
	
	  if (range) {
	    range.forAll(function (row, col) {
	      if (comparator(row, col)) {
	        result = true;
	
	        return false;
	      }
	    });
	  }
	
	  return result;
	}
	
	function markLabelAsSelected(label) {
	  // workaround for https://github.com/handsontable/handsontable/issues/1946
	  return '<span class="selected">' + String.fromCharCode(10003) + '</span>' + 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;
	}
	
	/***/ }),
	/* 20 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// Thank's IE8 for his funny defineProperty
	module.exports = !__webpack_require__(23)(function () {
	  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
	});
	
	
	/***/ }),
	/* 21 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 7.1.15 ToLength
	var toInteger = __webpack_require__(52);
	var min = Math.min;
	module.exports = function (it) {
	  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
	};
	
	
	/***/ }),
	/* 22 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _templateObject = _taggedTemplateLiteral(['\n          Your license key of Handsontable Pro has expired.\u200C\u200C\u200C\u200C \n          Renew your maintenance plan at https://handsontable.com or downgrade to the previous version of the software.\n          '], ['\n          Your license key of Handsontable Pro has expired.\u200C\u200C\u200C\u200C\\x20\n          Renew your maintenance plan at https://handsontable.com or downgrade to the previous version of the software.\n          ']);
	
	exports.stringify = stringify;
	exports.isDefined = isDefined;
	exports.isUndefined = isUndefined;
	exports.isEmpty = isEmpty;
	exports.isRegExp = isRegExp;
	exports._injectProductInfo = _injectProductInfo;
	
	var _moment = __webpack_require__(50);
	
	var _moment2 = _interopRequireDefault(_moment);
	
	var _templateLiteralTag = __webpack_require__(205);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
	
	/**
	 * Converts any value to string.
	 *
	 * @param {*} value
	 * @returns {String}
	 */
	function stringify(value) {
	  var result = void 0;
	
	  switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
	    case 'string':
	    case 'number':
	      result = '' + 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 ('' + 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;
	
	function _injectProductInfo(key, element) {
	  key = _norm(key || '');
	
	  var warningMessage = '';
	  var showDomMessage = true;
	  var schemaValidity = _checkKeySchema(key);
	  var ignored = _ignored();
	  var trial = isEmpty(key) || key === 'trial';
	
	  if (trial || schemaValidity) {
	    if (schemaValidity) {
	      var releaseTime = Math.floor((0, _moment2.default)('12/10/2017', 'DD/MM/YYYY').toDate().getTime() / 8.64e7);
	      var keyGenTime = _extractTime(key);
	
	      if (keyGenTime > 45000 || keyGenTime !== parseInt(keyGenTime, 10)) {
	        warningMessage = 'The license key provided to Handsontable Pro is invalid. Make sure you pass it correctly.';
	      }
	
	      if (!warningMessage) {
	        if (releaseTime > keyGenTime + 1) {
	          warningMessage = (0, _templateLiteralTag.toSingleLine)(_templateObject);
	        }
	        showDomMessage = releaseTime > keyGenTime + 15;
	      }
	    } else {
	      warningMessage = 'Evaluation version of Handsontable Pro. Not licensed for use in a production environment.';
	    }
	  } else {
	    warningMessage = 'The license key provided to Handsontable Pro is invalid. Make sure you pass it correctly.';
	  }
	  if (ignored) {
	    warningMessage = false;
	    showDomMessage = false;
	  }
	
	  if (warningMessage && !_notified) {
	    console[trial ? 'info' : 'warn'](warningMessage);
	    _notified = true;
	  }
	  if (showDomMessage && element.parentNode) {
	    var message = document.createElement('div');
	
	    message.id = 'hot-display-license-info';
	    message.appendChild(document.createTextNode('Evaluation version of Handsontable Pro.'));
	    message.appendChild(document.createElement('br'));
	    message.appendChild(document.createTextNode('Not licensed for production use.'));
	
	    element.parentNode.insertBefore(message, 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('' + _pi(_hd(c) + (_hd(_ss(v, Math.abs(j), 2)) + []).padStart(2, '0'))) % _cp('\xA2') || 2) >> 1 : c = _ss(v, j, !j ? 6 : i[_m] === 1 ? 9 : 8);
	  }
	
	  return p === z;
	}
	/* eslint-enable */
	
	/***/ }),
	/* 23 */
	/***/ (function(module, exports) {
	
	module.exports = function (exec) {
	  try {
	    return !!exec();
	  } catch (e) {
	    return true;
	  }
	};
	
	
	/***/ }),
	/* 24 */
	/***/ (function(module, exports) {
	
	var hasOwnProperty = {}.hasOwnProperty;
	module.exports = function (it, key) {
	  return hasOwnProperty.call(it, key);
	};
	
	
	/***/ }),
	/* 25 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// to indexed object, toObject with fallback for non-array-like ES3 strings
	var IObject = __webpack_require__(67);
	var defined = __webpack_require__(33);
	module.exports = function (it) {
	  return IObject(defined(it));
	};
	
	
	/***/ }),
	/* 26 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.isIE8 = isIE8;
	exports.isIE9 = isIE9;
	exports.isSafari = isSafari;
	exports.isChrome = isChrome;
	exports.isMobileBrowser = isMobileBrowser;
	
	var _isIE8 = !document.createTextNode('test').textContent;
	
	function isIE8() {
	  return _isIE8;
	}
	
	var _isIE9 = !!document.documentMode;
	
	function isIE9() {
	  return _isIE9;
	}
	
	var _isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
	
	function isSafari() {
	  return _isSafari;
	}
	
	var _isChrome = /Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor);
	
	function isChrome() {
	  return _isChrome;
	}
	
	function isMobileBrowser(userAgent) {
	  if (!userAgent) {
	    userAgent = navigator.userAgent;
	  }
	
	  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)
	  );
	}
	
	/***/ }),
	/* 27 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.getRegisteredValidators = exports.getRegisteredValidatorNames = exports.hasValidator = exports.getValidator = exports.registerValidator = undefined;
	
	var _staticRegister2 = __webpack_require__(63);
	
	var _staticRegister3 = _interopRequireDefault(_staticRegister2);
	
	var _autocompleteValidator = __webpack_require__(227);
	
	var _autocompleteValidator2 = _interopRequireDefault(_autocompleteValidator);
	
	var _dateValidator = __webpack_require__(228);
	
	var _dateValidator2 = _interopRequireDefault(_dateValidator);
	
	var _numericValidator = __webpack_require__(229);
	
	var _numericValidator2 = _interopRequireDefault(_numericValidator);
	
	var _timeValidator = __webpack_require__(230);
	
	var _timeValidator2 = _interopRequireDefault(_timeValidator);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var _staticRegister = (0, _staticRegister3.default)('validators'),
	    register = _staticRegister.register,
	    getItem = _staticRegister.getItem,
	    hasItem = _staticRegister.hasItem,
	    getNames = _staticRegister.getNames,
	    getValues = _staticRegister.getValues;
	
	register('autocomplete', _autocompleteValidator2.default);
	register('date', _dateValidator2.default);
	register('numeric', _numericValidator2.default);
	register('time', _timeValidator2.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 "' + name + '" name');
	  }
	
	  return getItem(name);
	}
	
	exports.registerValidator = register;
	exports.getValidator = _getItem;
	exports.hasValidator = hasItem;
	exports.getRegisteredValidatorNames = getNames;
	exports.getRegisteredValidators = getValues;
	
	/***/ }),
	/* 28 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var global = __webpack_require__(11);
	var hide = __webpack_require__(29);
	var has = __webpack_require__(24);
	var SRC = __webpack_require__(42)('src');
	var TO_STRING = 'toString';
	var $toString = Function[TO_STRING];
	var TPL = ('' + $toString).split(TO_STRING);
	
	__webpack_require__(44).inspectSource = function (it) {
	  return $toString.call(it);
	};
	
	(module.exports = function (O, key, val, safe) {
	  var isFunction = typeof val == 'function';
	  if (isFunction) has(val, 'name') || hide(val, 'name', key);
	  if (O[key] === val) return;
	  if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
	  if (O === global) {
	    O[key] = val;
	  } else if (!safe) {
	    delete O[key];
	    hide(O, key, val);
	  } else if (O[key]) {
	    O[key] = val;
	  } else {
	    hide(O, key, val);
	  }
	// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
	})(Function.prototype, TO_STRING, function toString() {
	  return typeof this == 'function' && this[SRC] || $toString.call(this);
	});
	
	
	/***/ }),
	/* 29 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var dP = __webpack_require__(17);
	var createDesc = __webpack_require__(43);
	module.exports = __webpack_require__(20) ? function (object, key, value) {
	  return dP.f(object, key, createDesc(1, value));
	} : function (object, key, value) {
	  object[key] = value;
	  return object;
	};
	
	
	/***/ }),
	/* 30 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// optional / simple context binding
	var aFunction = __webpack_require__(55);
	module.exports = function (fn, that, length) {
	  aFunction(fn);
	  if (that === undefined) return fn;
	  switch (length) {
	    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);
	  };
	};
	
	
	/***/ }),
	/* 31 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _object = __webpack_require__(1);
	
	var _array = __webpack_require__(2);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _core = __webpack_require__(159);
	
	var _core2 = _interopRequireDefault(_core);
	
	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"); } }
	
	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 = function () {
	  _createClass(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 (' + 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) {
	    _classCallCheck(this, Overlay);
	
	    (0, _object.defineGetter)(this, 'wot', wotInstance, {
	      writable: false
	    });
	
	    // legacy support, deprecated in the future
	    this.instance = this.wot;
	
	    this.type = '';
	    this.mainTableScrollableElement = null;
	    this.TABLE = this.wot.wtTable.TABLE;
	    this.hider = this.wot.wtTable.hider;
	    this.spreader = this.wot.wtTable.spreader;
	    this.holder = this.wot.wtTable.holder;
	    this.wtRootElement = this.wot.wtTable.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.
	   */
	
	
	  _createClass(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() {
	      this.mainTableScrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE);
	    }
	
	    /**
	     * 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 "' + direction + '" is not supported.');
	      }
	      var clone = document.createElement('DIV');
	      var clonedTable = document.createElement('TABLE');
	
	      clone.className = 'ht_clone_' + direction + ' handsontable';
	      clone.style.position = 'absolute';
	      clone.style.top = 0;
	      clone.style.left = 0;
	      clone.style.overflow = 'hidden';
	
	      clonedTable.className = this.wot.wtTable.TABLE.className;
	      clone.appendChild(clonedTable);
	
	      this.type = direction;
	      this.wot.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 = window;
	      } else {
	        this.mainTableScrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE);
	      }
	
	      return new _core2.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 _eventManager2.default(this.clone).destroy();
	    }
	  }]);
	
	  return Overlay;
	}();
	
	exports.default = Overlay;
	
	/***/ }),
	/* 32 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	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__(22);
	
	var _number = __webpack_require__(6);
	
	/**
	 * 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 = Array(_len), _key = 0; _key < _len; _key++) {
	    strings[_key] = arguments[_key];
	  }
	
	  var length = strings.length;
	
	  while (length--) {
	    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 ('' + 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) {
	  string += '';
	
	  return string.replace(STRIP_TAGS_REGEX, '');
	}
	
	/***/ }),
	/* 33 */
	/***/ (function(module, exports) {
	
	// 7.2.1 RequireObjectCoercible(argument)
	module.exports = function (it) {
	  if (it == undefined) throw TypeError("Can't call method on  " + it);
	  return it;
	};
	
	
	/***/ }),
	/* 34 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	exports.requestAnimationFrame = requestAnimationFrame;
	exports.cancelAnimationFrame = cancelAnimationFrame;
	exports.isTouchSupported = isTouchSupported;
	exports.isWebComponentSupportedNatively = isWebComponentSupportedNatively;
	exports.hasCaptionProblem = hasCaptionProblem;
	exports.getComparisonFunction = getComparisonFunction;
	// https://gist.github.com/paulirish/1579671
	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[vendors[x] + 'RequestAnimationFrame'];
	  _cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[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);
	}
	
	/**
	 * 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 = void 0;
	
	/**
	 * 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' : _typeof(Intl)) === 'object') {
	    comparisonFunction = new Intl.Collator(language, options).compare;
	  } else if (typeof String.prototype.localeCompare === 'function') {
	    comparisonFunction = function comparisonFunction(a, b) {
	      return ('' + a).localeCompare(b);
	    };
	  } else {
	    comparisonFunction = function comparisonFunction(a, b) {
	      if (a === b) {
	        return 0;
	      }
	
	      return a > b ? -1 : 1;
	    };
	  }
	
	  return comparisonFunction;
	}
	
	/***/ }),
	/* 35 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	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__(2);
	
	/**
	 * 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;
	
	    var args = arguments;
	    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() {
	    if (remainHits) {
	      remainHits--;
	
	      return func.apply(this, arguments);
	    }
	
	    return funcThrottle.apply(this, arguments);
	  }
	  _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 = void 0;
	
	  function _debounce() {
	    var _this2 = this;
	
	    var args = arguments;
	
	    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 _len = arguments.length, functions = Array(_len), _key = 0; _key < _len; _key++) {
	    functions[_key] = arguments[_key];
	  }
	
	  var firstFunc = functions[0],
	      restFunc = functions.slice(1);
	
	
	  return function _pipe() {
	    return (0, _array.arrayReduce)(restFunc, function (acc, fn) {
	      return fn(acc);
	    }, firstFunc.apply(this, arguments));
	  };
	}
	
	/**
	 * 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 _len2 = arguments.length, params = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
	    params[_key2 - 1] = arguments[_key2];
	  }
	
	  return function _partial() {
	    for (var _len3 = arguments.length, restParams = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
	      restParams[_key3] = arguments[_key3];
	    }
	
	    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 _len4 = arguments.length, params = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
	        params[_key4] = arguments[_key4];
	      }
	
	      var passedArgsSoFar = argsSoFar.concat(params);
	      var result = void 0;
	
	      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 _len5 = arguments.length, params = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
	        params[_key5] = arguments[_key5];
	      }
	
	      var passedArgsSoFar = argsSoFar.concat(params.reverse());
	      var result = void 0;
	
	      if (passedArgsSoFar.length >= argsLength) {
	        result = func.apply(this, passedArgsSoFar);
	      } else {
	        result = given(passedArgsSoFar);
	      }
	
	      return result;
	    };
	  }
	
	  return given([]);
	}
	
	/***/ }),
	/* 36 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 19.1.2.14 / 15.2.3.14 Object.keys(O)
	var $keys = __webpack_require__(92);
	var enumBugKeys = __webpack_require__(70);
	
	module.exports = Object.keys || function keys(O) {
	  return $keys(O, enumBugKeys);
	};
	
	
	/***/ }),
	/* 37 */
	/***/ (function(module, exports) {
	
	var toString = {}.toString;
	
	module.exports = function (it) {
	  return toString.call(it).slice(8, -1);
	};
	
	
	/***/ }),
	/* 38 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 7.1.13 ToObject(argument)
	var defined = __webpack_require__(33);
	module.exports = function (it) {
	  return Object(defined(it));
	};
	
	
	/***/ }),
	/* 39 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var isObject = __webpack_require__(14);
	module.exports = function (it, TYPE) {
	  if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');
	  return it;
	};
	
	
	/***/ }),
	/* 40 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 22.1.3.31 Array.prototype[@@unscopables]
	var UNSCOPABLES = __webpack_require__(9)('unscopables');
	var ArrayProto = Array.prototype;
	if (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(29)(ArrayProto, UNSCOPABLES, {});
	module.exports = function (key) {
	  ArrayProto[UNSCOPABLES][key] = true;
	};
	
	
	/***/ }),
	/* 41 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.EditorState = undefined;
	
	var _src = __webpack_require__(12);
	
	var _mixed = __webpack_require__(22);
	
	var EditorState = exports.EditorState = {
	  VIRGIN: 'STATE_VIRGIN', // before editing
	  EDITING: 'STATE_EDITING',
	  WAITING: 'STATE_WAITING', // waiting for async validation
	  FINISHED: 'STATE_FINISHED'
	};
	
	function BaseEditor(instance) {
	  this.instance = instance;
	  this.state = EditorState.VIRGIN;
	
	  this._opened = false;
	  this._fullEditMode = false;
	  this._closeCallback = null;
	
	  this.init();
	}
	
	BaseEditor.prototype._fireCallbacks = function (result) {
	  if (this._closeCallback) {
	    this._closeCallback(result);
	    this._closeCallback = null;
	  }
	};
	
	BaseEditor.prototype.init = function () {};
	
	BaseEditor.prototype.getValue = function () {
	  throw Error('Editor getValue() method unimplemented');
	};
	
	BaseEditor.prototype.setValue = function (newValue) {
	  throw Error('Editor setValue() method unimplemented');
	};
	
	BaseEditor.prototype.open = function () {
	  throw Error('Editor open() method unimplemented');
	};
	
	BaseEditor.prototype.close = function () {
	  throw Error('Editor close() method unimplemented');
	};
	
	BaseEditor.prototype.prepare = function (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;
	};
	
	BaseEditor.prototype.extend = function () {
	  var baseClass = this.constructor;
	
	  function Editor() {
	    baseClass.apply(this, arguments);
	  }
	
	  function inherit(Child, Parent) {
	    function Bridge() {}
	    Bridge.prototype = Parent.prototype;
	    Child.prototype = new Bridge();
	    Child.prototype.constructor = Child;
	
	    return Child;
	  }
	
	  return inherit(Editor, baseClass);
	};
	
	BaseEditor.prototype.saveValue = function (value, ctrlDown) {
	  var selection = void 0;
	  var tmp = void 0;
	
	  // if ctrl+enter and multiple cells selected, behave like Excel (finish editing and apply to all cells)
	  if (ctrlDown) {
	    selection = this.instance.getSelected();
	
	    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.instance.populateFromArray(selection[0], selection[1], value, selection[2], selection[3], 'edit');
	};
	
	BaseEditor.prototype.beginEditing = function (initialValue, event) {
	  if (this.state != EditorState.VIRGIN) {
	    return;
	  }
	  this.instance.view.scrollViewport(new _src.CellCoords(this.row, this.col));
	  this.instance.view.render();
	  this.state = EditorState.EDITING;
	
	  initialValue = typeof initialValue == 'string' ? initialValue : this.originalValue;
	  this.setValue((0, _mixed.stringify)(initialValue));
	
	  this.open(event);
	  this._opened = true;
	  this.focus();
	
	  // only rerender the selections (FillHandle should disappear when beginediting is triggered)
	  this.instance.view.render();
	
	  this.instance.runHooks('afterBeginEditing', this.row, this.col);
	};
	
	BaseEditor.prototype.finishEditing = function (restoreOriginalValue, ctrlDown, callback) {
	  var _this = this,
	      val;
	
	  if (callback) {
	    var previousCloseCallback = this._closeCallback;
	
	    this._closeCallback = function (result) {
	      if (previousCloseCallback) {
	        previousCloseCallback(result);
	      }
	
	      callback(result);
	      _this.instance.view.render();
	    };
	  }
	
	  if (this.isWaiting()) {
	    return;
	  }
	
	  if (this.state == EditorState.VIRGIN) {
	    this.instance._registerTimeout(setTimeout(function () {
	      _this._fireCallbacks(true);
	    }, 0));
	
	    return;
	  }
	
	  if (this.state == EditorState.EDITING) {
	    if (restoreOriginalValue) {
	      this.cancelChanges();
	      this.instance.view.render();
	
	      return;
	    }
	
	    var value = this.getValue();
	
	    if (this.instance.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.instance.getCellValidator(this.cellProperties)) {
	      this.instance.addHookOnce('postAfterValidate', function (result) {
	        _this.state = EditorState.FINISHED;
	        _this.discardEditor(result);
	      });
	    } else {
	      this.state = EditorState.FINISHED;
	      this.discardEditor(true);
	    }
	  }
	};
	
	BaseEditor.prototype.cancelChanges = function () {
	  this.state = EditorState.FINISHED;
	  this.discardEditor();
	};
	
	BaseEditor.prototype.discardEditor = function (result) {
	  if (this.state !== EditorState.FINISHED) {
	    return;
	  }
	  // validator was defined and failed
	  if (result === false && this.cellProperties.allowInvalid !== true) {
	    this.instance.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.
	 */
	BaseEditor.prototype.enableFullEditMode = function () {
	  this._fullEditMode = true;
	};
	
	/**
	 * Checks if editor is in full edit mode.
	 *
	 * @returns {Boolean}
	 */
	BaseEditor.prototype.isInFullEditMode = function () {
	  return this._fullEditMode;
	};
	
	BaseEditor.prototype.isOpened = function () {
	  return this._opened;
	};
	
	BaseEditor.prototype.isWaiting = function () {
	  return this.state === EditorState.WAITING;
	};
	
	BaseEditor.prototype.checkEditorSection = function () {
	  var totalRows = this.instance.countRows();
	  var section = '';
	
	  if (this.row < this.instance.getSettings().fixedRowsTop) {
	    if (this.col < this.instance.getSettings().fixedColumnsLeft) {
	      section = 'top-left-corner';
	    } else {
	      section = 'top';
	    }
	  } else if (this.instance.getSettings().fixedRowsBottom && this.row >= totalRows - this.instance.getSettings().fixedRowsBottom) {
	    if (this.col < this.instance.getSettings().fixedColumnsLeft) {
	      section = 'bottom-left-corner';
	    } else {
	      section = 'bottom';
	    }
	  } else if (this.col < this.instance.getSettings().fixedColumnsLeft) {
	    section = 'left';
	  }
	
	  return section;
	};
	
	exports.default = BaseEditor;
	
	/***/ }),
	/* 42 */
	/***/ (function(module, exports) {
	
	var id = 0;
	var px = Math.random();
	module.exports = function (key) {
	  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
	};
	
	
	/***/ }),
	/* 43 */
	/***/ (function(module, exports) {
	
	module.exports = function (bitmap, value) {
	  return {
	    enumerable: !(bitmap & 1),
	    configurable: !(bitmap & 2),
	    writable: !(bitmap & 4),
	    value: value
	  };
	};
	
	
	/***/ }),
	/* 44 */
	/***/ (function(module, exports) {
	
	var core = module.exports = { version: '2.5.1' };
	if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
	
	
	/***/ }),
	/* 45 */
	/***/ (function(module, exports) {
	
	module.exports = {};
	
	
	/***/ }),
	/* 46 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var def = __webpack_require__(17).f;
	var has = __webpack_require__(24);
	var TAG = __webpack_require__(9)('toStringTag');
	
	module.exports = function (it, tag, stat) {
	  if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
	};
	
	
	/***/ }),
	/* 47 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var META = __webpack_require__(42)('meta');
	var isObject = __webpack_require__(14);
	var has = __webpack_require__(24);
	var setDesc = __webpack_require__(17).f;
	var id = 0;
	var isExtensible = Object.isExtensible || function () {
	  return true;
	};
	var FREEZE = !__webpack_require__(23)(function () {
	  return isExtensible(Object.preventExtensions({}));
	});
	var setMeta = function (it) {
	  setDesc(it, META, { value: {
	    i: 'O' + ++id, // object ID
	    w: {}          // weak collections IDs
	  } });
	};
	var fastKey = function (it, create) {
	  // return primitive with prefix
	  if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
	  if (!has(it, META)) {
	    // 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
	    setMeta(it);
	  // return object ID
	  } return it[META].i;
	};
	var getWeak = function (it, create) {
	  if (!has(it, META)) {
	    // 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
	    setMeta(it);
	  // return hash weak collections IDs
	  } return it[META].w;
	};
	// add metadata on freeze-family methods calling
	var onFreeze = function (it) {
	  if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);
	  return it;
	};
	var meta = module.exports = {
	  KEY: META,
	  NEED: false,
	  fastKey: fastKey,
	  getWeak: getWeak,
	  onFreeze: onFreeze
	};
	
	
	/***/ }),
	/* 48 */
	/***/ (function(module, exports) {
	
	exports.f = {}.propertyIsEnumerable;
	
	
	/***/ }),
	/* 49 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * CellCoords holds cell coordinates (row, column) and few method to validate them and
	 * retrieve as an array or an object
	 *
	 * @class CellCoords
	 */
	var CellCoords = function () {
	  /**
	   * @param {Number} row Row index
	   * @param {Number} col Column index
	   */
	  function CellCoords(row, col) {
	    _classCallCheck(this, CellCoords);
	
	    if (typeof row !== 'undefined' && typeof col !== 'undefined') {
	      this.row = row;
	      this.col = col;
	    } else {
	      this.row = null;
	      this.col = null;
	    }
	  }
	
	  /**
	   * Checks if given set of coordinates is valid in context of a given Walkontable instance
	   *
	   * @param {Walkontable} wotInstance
	   * @returns {Boolean}
	   */
	
	
	  _createClass(CellCoords, [{
	    key: 'isValid',
	    value: function isValid(wotInstance) {
	      // 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 >= wotInstance.getSetting('totalRows') || this.col >= wotInstance.getSetting('totalColumns')) {
	        return false;
	      }
	
	      return true;
	    }
	
	    /**
	     * Checks if this cell coords are the same as cell coords given as a parameter
	     *
	     * @param {CellCoords} cellCoords
	     * @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 coords
	     *
	     * @param {Object} testedCoords
	     * @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 coords
	     *
	     * @param {Object} testedCoords
	     * @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 coords
	     *
	     * @param {Object} testedCoords
	     * @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 coords
	     *
	     * @param {Object} testedCoords
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'isNorthEastOf',
	    value: function isNorthEastOf(testedCoords) {
	      return this.row <= testedCoords.row && this.col >= testedCoords.col;
	    }
	  }]);
	
	  return CellCoords;
	}();
	
	exports.default = CellCoords;
	
	/***/ }),
	/* 50 */
	/***/ (function(module, exports) {
	
	module.exports = __WEBPACK_EXTERNAL_MODULE_50__;
	
	/***/ }),
	/* 51 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _autoResize = __webpack_require__(210);
	
	var _autoResize2 = _interopRequireDefault(_autoResize);
	
	var _baseEditor = __webpack_require__(41);
	
	var _baseEditor2 = _interopRequireDefault(_baseEditor);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _unicode = __webpack_require__(18);
	
	var _event = __webpack_require__(10);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var TextEditor = _baseEditor2.default.prototype.extend();
	
	/**
	 * @private
	 * @editor TextEditor
	 * @class TextEditor
	 * @dependencies autoResize
	 */
	TextEditor.prototype.init = function () {
	  var that = this;
	  this.createElements();
	  this.eventManager = new _eventManager2.default(this);
	  this.bindEvents();
	  this.autoResize = (0, _autoResize2.default)();
	
	  this.instance.addHook('afterDestroy', function () {
	    that.destroy();
	  });
	};
	
	TextEditor.prototype.getValue = function () {
	  return this.TEXTAREA.value;
	};
	
	TextEditor.prototype.setValue = function (newValue) {
	  this.TEXTAREA.value = newValue;
	};
	
	var onBeforeKeyDown = function onBeforeKeyDown(event) {
	  var instance = this,
	      that = instance.getActiveEditor(),
	      ctrlDown;
	
	  // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
	  ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
	
	  // Process only events that have been fired in the editor
	  if (event.target !== that.TEXTAREA || (0, _event.isImmediatePropagationStopped)(event)) {
	    return;
	  }
	
	  if (event.keyCode === 17 || event.keyCode === 224 || event.keyCode === 91 || event.keyCode === 93) {
	    // when CTRL or its equivalent is pressed and cell is edited, don't prepare selectable text in textarea
	    (0, _event.stopImmediatePropagation)(event);
	    return;
	  }
	
	  switch (event.keyCode) {
	    case _unicode.KEY_CODES.ARROW_RIGHT:
	      if (that.isInFullEditMode()) {
	        if (!that.isWaiting() && !that.allowKeyEventPropagation || !that.isWaiting() && that.allowKeyEventPropagation && !that.allowKeyEventPropagation(event.keyCode)) {
	          (0, _event.stopImmediatePropagation)(event);
	        }
	      }
	      break;
	    case _unicode.KEY_CODES.ARROW_LEFT:
	      if (that.isInFullEditMode()) {
	        if (!that.isWaiting() && !that.allowKeyEventPropagation || !that.isWaiting() && that.allowKeyEventPropagation && !that.allowKeyEventPropagation(event.keyCode)) {
	          (0, _event.stopImmediatePropagation)(event);
	        }
	      }
	      break;
	    case _unicode.KEY_CODES.ARROW_UP:
	    case _unicode.KEY_CODES.ARROW_DOWN:
	      if (that.isInFullEditMode()) {
	        if (!that.isWaiting() && !that.allowKeyEventPropagation || !that.isWaiting() && that.allowKeyEventPropagation && !that.allowKeyEventPropagation(event.keyCode)) {
	          (0, _event.stopImmediatePropagation)(event);
	        }
	      }
	      break;
	
	    case _unicode.KEY_CODES.ENTER:
	      var selected = that.instance.getSelected();
	      var isMultipleSelection = !(selected[0] === selected[2] && selected[1] === selected[3]);
	      if (ctrlDown && !isMultipleSelection || event.altKey) {
	        // if ctrl+enter or alt+enter, add new line
	        if (that.isOpened()) {
	          var caretPosition = (0, _element.getCaretPosition)(that.TEXTAREA),
	              value = that.getValue();
	
	          var newValue = value.slice(0, caretPosition) + '\n' + value.slice(caretPosition);
	
	          that.setValue(newValue);
	
	          (0, _element.setCaretPosition)(that.TEXTAREA, caretPosition + 1);
	        } else {
	          that.beginEditing(that.originalValue + '\n');
	        }
	        (0, _event.stopImmediatePropagation)(event);
	      }
	      event.preventDefault(); // don't add newline to field
	      break;
	
	    case _unicode.KEY_CODES.A:
	    case _unicode.KEY_CODES.X:
	    case _unicode.KEY_CODES.C:
	    case _unicode.KEY_CODES.V:
	      if (ctrlDown) {
	        (0, _event.stopImmediatePropagation)(event); // CTRL+A, CTRL+C, CTRL+V, CTRL+X should only work locally when cell is edited (not in table context)
	      }
	      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) {
	    that.autoResize.resize(String.fromCharCode(event.keyCode));
	  }
	};
	
	TextEditor.prototype.open = function () {
	  this.refreshDimensions(); // need it instantly, to prevent https://github.com/handsontable/handsontable/issues/348
	
	  this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
	};
	
	TextEditor.prototype.close = function (tdOutside) {
	  this.textareaParentStyle.display = 'none';
	
	  this.autoResize.unObserve();
	
	  if (document.activeElement === this.TEXTAREA) {
	    this.instance.listen(); // don't refocus the table if user focused some cell outside of HT on purpose
	  }
	  this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
	};
	
	TextEditor.prototype.focus = function () {
	  this.TEXTAREA.focus();
	  (0, _element.setCaretPosition)(this.TEXTAREA, this.TEXTAREA.value.length);
	};
	
	TextEditor.prototype.createElements = function () {
	  //    this.$body = $(document.body);
	
	  this.TEXTAREA = document.createElement('TEXTAREA');
	
	  (0, _element.addClass)(this.TEXTAREA, 'handsontableInput');
	
	  this.textareaStyle = this.TEXTAREA.style;
	  this.textareaStyle.width = 0;
	  this.textareaStyle.height = 0;
	
	  this.TEXTAREA_PARENT = document.createElement('DIV');
	  (0, _element.addClass)(this.TEXTAREA_PARENT, 'handsontableInputHolder');
	
	  this.textareaParentStyle = this.TEXTAREA_PARENT.style;
	  this.textareaParentStyle.top = 0;
	  this.textareaParentStyle.left = 0;
	  this.textareaParentStyle.display = 'none';
	
	  this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
	
	  this.instance.rootElement.appendChild(this.TEXTAREA_PARENT);
	
	  var that = this;
	  this.instance._registerTimeout(setTimeout(function () {
	    that.refreshDimensions();
	  }, 0));
	};
	
	TextEditor.prototype.getEditedCell = function () {
	  var editorSection = this.checkEditorSection(),
	      editedCell;
	
	  switch (editorSection) {
	    case 'top':
	      editedCell = this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.textareaParentStyle.zIndex = 101;
	      break;
	    case 'top-left-corner':
	      editedCell = this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.textareaParentStyle.zIndex = 103;
	      break;
	    case 'bottom-left-corner':
	      editedCell = this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.textareaParentStyle.zIndex = 103;
	      break;
	    case 'left':
	      editedCell = this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.textareaParentStyle.zIndex = 102;
	      break;
	    case 'bottom':
	      editedCell = this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.textareaParentStyle.zIndex = 102;
	      break;
	    default:
	      editedCell = this.instance.getCell(this.row, this.col);
	      this.textareaParentStyle.zIndex = '';
	      break;
	  }
	
	  return editedCell != -1 && editedCell != -2 ? editedCell : void 0;
	};
	
	TextEditor.prototype.refreshValue = function () {
	  var sourceData = this.instance.getSourceDataAtCell(this.row, this.prop);
	  this.originalValue = sourceData;
	
	  this.setValue(sourceData);
	  this.refreshDimensions();
	};
	
	TextEditor.prototype.refreshDimensions = function () {
	  if (this.state !== _baseEditor.EditorState.EDITING) {
	    return;
	  }
	  this.TD = this.getEditedCell();
	
	  // TD is outside of the viewport.
	  if (!this.TD) {
	    this.close(true);
	
	    return;
	  }
	  var currentOffset = (0, _element.offset)(this.TD),
	      containerOffset = (0, _element.offset)(this.instance.rootElement),
	      scrollableContainer = (0, _element.getScrollableElement)(this.TD),
	      totalRowsCount = this.instance.countRows(),
	
	
	  // If colHeaders is disabled, cells in the first row have border-top
	  editTopModifier = currentOffset.top === containerOffset.top ? 0 : 1,
	      editTop = currentOffset.top - containerOffset.top - editTopModifier - (scrollableContainer.scrollTop || 0),
	      editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0),
	      settings = this.instance.getSettings(),
	      rowHeadersCount = this.instance.hasRowHeaders(),
	      colHeadersCount = this.instance.hasColHeaders(),
	      editorSection = this.checkEditorSection(),
	      backgroundColor = this.TD.style.backgroundColor,
	      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)(this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'left':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'top-left-corner':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'bottom-left-corner':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'bottom':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode);
	      break;
	    default:
	      break;
	  }
	
	  if (colHeadersCount && this.instance.getSelected()[0] === 0 || settings.fixedRowsBottom && this.instance.getSelected()[0] === totalRowsCount - settings.fixedRowsBottom) {
	    editTop += 1;
	  }
	
	  if (this.instance.getSelected()[1] === 0) {
	    editLeft += 1;
	  }
	
	  if (cssTransformOffset && cssTransformOffset != -1) {
	    this.textareaParentStyle[cssTransformOffset[0]] = cssTransformOffset[1];
	  } else {
	    (0, _element.resetCssTransform)(this.TEXTAREA_PARENT);
	  }
	
	  this.textareaParentStyle.top = editTop + 'px';
	  this.textareaParentStyle.left = editLeft + 'px';
	
	  var firstRowOffset = this.instance.view.wt.wtViewport.rowsRenderCalculator.startPosition;
	  var firstColumnOffset = this.instance.view.wt.wtViewport.columnsRenderCalculator.startPosition;
	  var horizontalScrollPosition = this.instance.view.wt.wtOverlays.leftOverlay.getScrollPosition();
	  var verticalScrollPosition = this.instance.view.wt.wtOverlays.topOverlay.getScrollPosition();
	  var scrollbarWidth = (0, _element.getScrollbarWidth)();
	
	  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)(scrollableContainer) ? scrollbarWidth : 0;
	  var actualHorizontalScrollbarWidth = (0, _element.hasHorizontalScrollbar)(scrollableContainer) ? scrollbarWidth : 0;
	  var maxWidth = this.instance.view.maximumVisibleElementWidth(cellLeftOffset) - 9 - actualVerticalScrollbarWidth;
	  var height = this.TD.scrollHeight + 1;
	  var maxHeight = Math.max(this.instance.view.maximumVisibleElementHeight(cellTopOffset) - actualHorizontalScrollbarWidth, 23);
	
	  var cellComputedStyle = (0, _element.getComputedStyle)(this.TD);
	
	  this.TEXTAREA.style.fontSize = cellComputedStyle.fontSize;
	  this.TEXTAREA.style.fontFamily = cellComputedStyle.fontFamily;
	  this.TEXTAREA.style.backgroundColor = ''; // RESET STYLE
	  this.TEXTAREA.style.backgroundColor = backgroundColor ? backgroundColor : (0, _element.getComputedStyle)(this.TEXTAREA).backgroundColor;
	
	  this.autoResize.init(this.TEXTAREA, {
	    minHeight: Math.min(height, maxHeight),
	    maxHeight: maxHeight, // TEXTAREA should never be wider 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);
	
	  this.textareaParentStyle.display = 'block';
	};
	
	TextEditor.prototype.bindEvents = function () {
	  var editor = this;
	
	  this.eventManager.addEventListener(this.TEXTAREA, 'cut', function (event) {
	    (0, _event.stopPropagation)(event);
	  });
	
	  this.eventManager.addEventListener(this.TEXTAREA, 'paste', function (event) {
	    (0, _event.stopPropagation)(event);
	  });
	
	  this.instance.addHook('afterScrollHorizontally', function () {
	    editor.refreshDimensions();
	  });
	
	  this.instance.addHook('afterScrollVertically', function () {
	    editor.refreshDimensions();
	  });
	
	  this.instance.addHook('afterColumnResize', function () {
	    editor.refreshDimensions();
	    editor.focus();
	  });
	
	  this.instance.addHook('afterRowResize', function () {
	    editor.refreshDimensions();
	    editor.focus();
	  });
	
	  this.instance.addHook('afterDestroy', function () {
	    editor.eventManager.destroy();
	  });
	};
	
	TextEditor.prototype.destroy = function () {
	  this.eventManager.destroy();
	};
	
	exports.default = TextEditor;
	
	/***/ }),
	/* 52 */
	/***/ (function(module, exports) {
	
	// 7.1.4 ToInteger
	var ceil = Math.ceil;
	var floor = Math.floor;
	module.exports = function (it) {
	  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
	};
	
	
	/***/ }),
	/* 53 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var toInteger = __webpack_require__(52);
	var max = Math.max;
	var min = Math.min;
	module.exports = function (index, length) {
	  index = toInteger(index);
	  return index < 0 ? max(index + length, 0) : min(index, length);
	};
	
	
	/***/ }),
	/* 54 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var redefine = __webpack_require__(28);
	module.exports = function (target, src, safe) {
	  for (var key in src) redefine(target, key, src[key], safe);
	  return target;
	};
	
	
	/***/ }),
	/* 55 */
	/***/ (function(module, exports) {
	
	module.exports = function (it) {
	  if (typeof it != 'function') throw TypeError(it + ' is not a function!');
	  return it;
	};
	
	
	/***/ }),
	/* 56 */
	/***/ (function(module, exports) {
	
	module.exports = function (it, Constructor, name, forbiddenField) {
	  if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {
	    throw TypeError(name + ': incorrect invocation!');
	  } return it;
	};
	
	
	/***/ }),
	/* 57 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var ctx = __webpack_require__(30);
	var call = __webpack_require__(95);
	var isArrayIter = __webpack_require__(96);
	var anObject = __webpack_require__(16);
	var toLength = __webpack_require__(21);
	var getIterFn = __webpack_require__(97);
	var BREAK = {};
	var RETURN = {};
	var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {
	  var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);
	  var f = ctx(fn, that, entries ? 2 : 1);
	  var index = 0;
	  var length, step, iterator, result;
	  if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
	  // fast case for arrays with default iterator
	  if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {
	    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
	    if (result === BREAK || result === RETURN) return result;
	  } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
	    result = call(iterator, f, step.value, entries);
	    if (result === BREAK || result === RETURN) return result;
	  }
	};
	exports.BREAK = BREAK;
	exports.RETURN = RETURN;
	
	
	/***/ }),
	/* 58 */
	/***/ (function(module, exports) {
	
	module.exports = false;
	
	
	/***/ }),
	/* 59 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var global = __webpack_require__(11);
	var $export = __webpack_require__(3);
	var redefine = __webpack_require__(28);
	var redefineAll = __webpack_require__(54);
	var meta = __webpack_require__(47);
	var forOf = __webpack_require__(57);
	var anInstance = __webpack_require__(56);
	var isObject = __webpack_require__(14);
	var fails = __webpack_require__(23);
	var $iterDetect = __webpack_require__(71);
	var setToStringTag = __webpack_require__(46);
	var inheritIfRequired = __webpack_require__(184);
	
	module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {
	  var Base = global[NAME];
	  var C = Base;
	  var ADDER = IS_MAP ? 'set' : 'add';
	  var proto = C && C.prototype;
	  var O = {};
	  var fixMethod = function (KEY) {
	    var fn = proto[KEY];
	    redefine(proto, KEY,
	      KEY == 'delete' ? function (a) {
	        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
	      } : KEY == 'has' ? function has(a) {
	        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
	      } : KEY == 'get' ? function get(a) {
	        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
	      } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; }
	        : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; }
	    );
	  };
	  if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () {
	    new C().entries().next();
	  }))) {
	    // create collection constructor
	    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
	    redefineAll(C.prototype, methods);
	    meta.NEED = true;
	  } else {
	    var instance = new C();
	    // 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
	    var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new
	    // 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 C();
	      var index = 5;
	      while (index--) $instance[ADDER](index, index);
	      return !$instance.has(-0);
	    });
	    if (!ACCEPT_ITERABLES) {
	      C = wrapper(function (target, iterable) {
	        anInstance(target, C, NAME);
	        var that = inheritIfRequired(new Base(), target, C);
	        if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
	        return that;
	      });
	      C.prototype = proto;
	      proto.constructor = C;
	    }
	    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 && proto.clear) delete proto.clear;
	  }
	
	  setToStringTag(C, NAME);
	
	  O[NAME] = C;
	  $export($export.G + $export.W + $export.F * (C != Base), O);
	
	  if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);
	
	  return C;
	};
	
	
	/***/ }),
	/* 60 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 0 -> Array#forEach
	// 1 -> Array#map
	// 2 -> Array#filter
	// 3 -> Array#some
	// 4 -> Array#every
	// 5 -> Array#find
	// 6 -> Array#findIndex
	var ctx = __webpack_require__(30);
	var IObject = __webpack_require__(67);
	var toObject = __webpack_require__(38);
	var toLength = __webpack_require__(21);
	var asc = __webpack_require__(185);
	module.exports = function (TYPE, $create) {
	  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 = $create || asc;
	  return function ($this, callbackfn, that) {
	    var O = toObject($this);
	    var self = IObject(O);
	    var f = ctx(callbackfn, that, 3);
	    var length = toLength(self.length);
	    var index = 0;
	    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
	    var val, res;
	    for (;length > index; index++) if (NO_HOLES || index in self) {
	      val = self[index];
	      res = f(val, index, O);
	      if (TYPE) {
	        if (IS_MAP) result[index] = res;   // map
	        else if (res) switch (TYPE) {
	          case 3: return true;             // some
	          case 5: return val;              // find
	          case 6: return index;            // findIndex
	          case 2: result.push(val);        // filter
	        } else if (IS_EVERY) return false; // every
	      }
	    }
	    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
	  };
	};
	
	
	/***/ }),
	/* 61 */
	/***/ (function(module, exports) {
	
	exports.f = Object.getOwnPropertySymbols;
	
	
	/***/ }),
	/* 62 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var hide = __webpack_require__(29);
	var redefine = __webpack_require__(28);
	var fails = __webpack_require__(23);
	var defined = __webpack_require__(33);
	var wks = __webpack_require__(9);
	
	module.exports = function (KEY, length, exec) {
	  var SYMBOL = wks(KEY);
	  var fns = exec(defined, SYMBOL, ''[KEY]);
	  var strfn = fns[0];
	  var rxfn = fns[1];
	  if (fails(function () {
	    var O = {};
	    O[SYMBOL] = function () { return 7; };
	    return ''[KEY](O) != 7;
	  })) {
	    redefine(String.prototype, KEY, strfn);
	    hide(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 rxfn.call(string, this, arg); }
	      // 21.2.5.6 RegExp.prototype[@@match](string)
	      // 21.2.5.9 RegExp.prototype[@@search](string)
	      : function (string) { return rxfn.call(string, this); }
	    );
	  }
	};
	
	
	/***/ }),
	/* 63 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = staticRegister;
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	var collection = exports.collection = new Map();
	
	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 [].concat(_toConsumableArray(subCollection.keys()));
	  }
	
	  /**
	   * Retrieve all registered values from the collection.
	   *
	   * @returns {Array} Returns an array with all values stored in the collection.
	   */
	  function getValues() {
	    return [].concat(_toConsumableArray(subCollection.values()));
	  }
	
	  return {
	    register: register,
	    getItem: getItem,
	    hasItem: hasItem,
	    getNames: getNames,
	    getValues: getValues
	  };
	}
	
	/***/ }),
	/* 64 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var isObject = __webpack_require__(14);
	var document = __webpack_require__(11).document;
	// typeof document.createElement is 'object' in old IE
	var is = isObject(document) && isObject(document.createElement);
	module.exports = function (it) {
	  return is ? document.createElement(it) : {};
	};
	
	
	/***/ }),
	/* 65 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 7.1.1 ToPrimitive(input [, PreferredType])
	var isObject = __webpack_require__(14);
	// 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");
	};
	
	
	/***/ }),
	/* 66 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
	var anObject = __webpack_require__(16);
	var dPs = __webpack_require__(181);
	var enumBugKeys = __webpack_require__(70);
	var IE_PROTO = __webpack_require__(68)('IE_PROTO');
	var Empty = function () { /* empty */ };
	var PROTOTYPE = 'prototype';
	
	// Create object with fake `null` prototype: use iframe Object with cleared prototype
	var createDict = function () {
	  // Thrash, waste and sodomy: IE GC bug
	  var iframe = __webpack_require__(64)('iframe');
	  var i = enumBugKeys.length;
	  var lt = '<';
	  var gt = '>';
	  var iframeDocument;
	  iframe.style.display = 'none';
	  __webpack_require__(94).appendChild(iframe);
	  iframe.src = 'javascript:'; // eslint-disable-line no-script-url
	  // createDict = iframe.contentWindow.Object;
	  // html.removeChild(iframe);
	  iframeDocument = iframe.contentWindow.document;
	  iframeDocument.open();
	  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
	  iframeDocument.close();
	  createDict = iframeDocument.F;
	  while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];
	  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 : dPs(result, Properties);
	};
	
	
	/***/ }),
	/* 67 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// fallback for non-array-like ES3 and non-enumerable old V8 strings
	var cof = __webpack_require__(37);
	// eslint-disable-next-line no-prototype-builtins
	module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
	  return cof(it) == 'String' ? it.split('') : Object(it);
	};
	
	
	/***/ }),
	/* 68 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var shared = __webpack_require__(69)('keys');
	var uid = __webpack_require__(42);
	module.exports = function (key) {
	  return shared[key] || (shared[key] = uid(key));
	};
	
	
	/***/ }),
	/* 69 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var global = __webpack_require__(11);
	var SHARED = '__core-js_shared__';
	var store = global[SHARED] || (global[SHARED] = {});
	module.exports = function (key) {
	  return store[key] || (store[key] = {});
	};
	
	
	/***/ }),
	/* 70 */
	/***/ (function(module, exports) {
	
	// IE 8- don't enum bug keys
	module.exports = (
	  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
	).split(',');
	
	
	/***/ }),
	/* 71 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var ITERATOR = __webpack_require__(9)('iterator');
	var SAFE_CLOSING = false;
	
	try {
	  var riter = [7][ITERATOR]();
	  riter['return'] = function () { SAFE_CLOSING = true; };
	  // eslint-disable-next-line no-throw-literal
	  Array.from(riter, function () { throw 2; });
	} catch (e) { /* empty */ }
	
	module.exports = function (exec, skipClosing) {
	  if (!skipClosing && !SAFE_CLOSING) return false;
	  var safe = false;
	  try {
	    var arr = [7];
	    var iter = arr[ITERATOR]();
	    iter.next = function () { return { done: safe = true }; };
	    arr[ITERATOR] = function () { return iter; };
	    exec(arr);
	  } catch (e) { /* empty */ }
	  return safe;
	};
	
	
	/***/ }),
	/* 72 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var pIE = __webpack_require__(48);
	var createDesc = __webpack_require__(43);
	var toIObject = __webpack_require__(25);
	var toPrimitive = __webpack_require__(65);
	var has = __webpack_require__(24);
	var IE8_DOM_DEFINE = __webpack_require__(91);
	var gOPD = Object.getOwnPropertyDescriptor;
	
	exports.f = __webpack_require__(20) ? gOPD : function getOwnPropertyDescriptor(O, P) {
	  O = toIObject(O);
	  P = toPrimitive(P, true);
	  if (IE8_DOM_DEFINE) try {
	    return gOPD(O, P);
	  } catch (e) { /* empty */ }
	  if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);
	};
	
	
	/***/ }),
	/* 73 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var ctx = __webpack_require__(30);
	var invoke = __webpack_require__(188);
	var html = __webpack_require__(94);
	var cel = __webpack_require__(64);
	var global = __webpack_require__(11);
	var process = global.process;
	var setTask = global.setImmediate;
	var clearTask = global.clearImmediate;
	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 (!setTask || !clearTask) {
	  setTask = 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
	      invoke(typeof fn == 'function' ? fn : Function(fn), args);
	    };
	    defer(counter);
	    return counter;
	  };
	  clearTask = function clearImmediate(id) {
	    delete queue[id];
	  };
	  // Node.js 0.8-
	  if (__webpack_require__(37)(process) == 'process') {
	    defer = function (id) {
	      process.nextTick(ctx(run, id, 1));
	    };
	  // Sphere (JS game engine) Dispatch API
	  } else if (Dispatch && Dispatch.now) {
	    defer = function (id) {
	      Dispatch.now(ctx(run, id, 1));
	    };
	  // Browsers with MessageChannel, includes WebWorkers
	  } else if (MessageChannel) {
	    channel = new MessageChannel();
	    port = channel.port2;
	    channel.port1.onmessage = listener;
	    defer = ctx(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 cel('script')) {
	    defer = function (id) {
	      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {
	        html.removeChild(this);
	        run.call(id);
	      };
	    };
	  // Rest old browsers
	  } else {
	    defer = function (id) {
	      setTimeout(ctx(run, id, 1), 0);
	    };
	  }
	}
	module.exports = {
	  set: setTask,
	  clear: clearTask
	};
	
	
	/***/ }),
	/* 74 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
	var $keys = __webpack_require__(92);
	var hiddenKeys = __webpack_require__(70).concat('length', 'prototype');
	
	exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
	  return $keys(O, hiddenKeys);
	};
	
	
	/***/ }),
	/* 75 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// helper for String#{startsWith, endsWith, includes}
	var isRegExp = __webpack_require__(123);
	var defined = __webpack_require__(33);
	
	module.exports = function (that, searchString, NAME) {
	  if (isRegExp(searchString)) throw TypeError('String#' + NAME + " doesn't accept regex!");
	  return String(defined(that));
	};
	
	
	/***/ }),
	/* 76 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var MATCH = __webpack_require__(9)('match');
	module.exports = function (KEY) {
	  var re = /./;
	  try {
	    '/./'[KEY](re);
	  } catch (e) {
	    try {
	      re[MATCH] = false;
	      return !'/./'[KEY](re);
	    } catch (f) { /* empty */ }
	  } return true;
	};
	
	
	/***/ }),
	/* 77 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var $defineProperty = __webpack_require__(17);
	var createDesc = __webpack_require__(43);
	
	module.exports = function (object, index, value) {
	  if (index in object) $defineProperty.f(object, index, createDesc(0, value));
	  else object[index] = value;
	};
	
	
	/***/ }),
	/* 78 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var addToUnscopables = __webpack_require__(40);
	var step = __webpack_require__(100);
	var Iterators = __webpack_require__(45);
	var toIObject = __webpack_require__(25);
	
	// 22.1.3.4 Array.prototype.entries()
	// 22.1.3.13 Array.prototype.keys()
	// 22.1.3.29 Array.prototype.values()
	// 22.1.3.30 Array.prototype[@@iterator]()
	module.exports = __webpack_require__(99)(Array, 'Array', function (iterated, kind) {
	  this._t = toIObject(iterated); // target
	  this._i = 0;                   // next index
	  this._k = kind;                // kind
	// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
	}, function () {
	  var O = this._t;
	  var kind = this._k;
	  var index = this._i++;
	  if (!O || index >= O.length) {
	    this._t = undefined;
	    return step(1);
	  }
	  if (kind == 'keys') return step(0, index);
	  if (kind == 'values') return step(0, O[index]);
	  return step(0, [index, O[index]]);
	}, 'values');
	
	// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
	Iterators.Arguments = Iterators.Array;
	
	addToUnscopables('keys');
	addToUnscopables('values');
	addToUnscopables('entries');
	
	
	/***/ }),
	/* 79 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _coords = __webpack_require__(49);
	
	var _coords2 = _interopRequireDefault(_coords);
	
	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"); } }
	
	/**
	 * A cell range is a set of exactly two CellCoords (that can be the same or different)
	 *
	 * @class CellRange
	 */
	var CellRange = function () {
	  /**
	   * @param {CellCoords} highlight Used to draw bold border around a cell where selection was
	   *                                          started and to edit the cell when you press Enter
	   * @param {CellCoords} from Usually the same as highlight, but in Excel there is distinction - one can change
	   *                                     highlight within a selection
	   * @param {CellCoords} to End selection
	   */
	  function CellRange(highlight, from, to) {
	    _classCallCheck(this, CellRange);
	
	    this.highlight = highlight;
	    this.from = from;
	    this.to = to;
	  }
	
	  /**
	   * Checks if given coords are valid in context of a given Walkontable instance
	   *
	   * @param {Walkontable} wotInstance
	   * @returns {Boolean}
	   */
	
	
	  _createClass(CellRange, [{
	    key: 'isValid',
	    value: function isValid(wotInstance) {
	      return this.from.isValid(wotInstance) && this.to.isValid(wotInstance);
	    }
	
	    /**
	     * 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 coords is within `from` and `to` cell coords of this range
	     *
	     * @param {CellCoords} cellCoords
	     * @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} testedRange
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'includesRange',
	    value: function includesRange(testedRange) {
	      return this.includes(testedRange.getTopLeftCorner()) && this.includes(testedRange.getBottomRightCorner());
	    }
	
	    /**
	     * Checks if given range is equal to this range
	     *
	     * @param {CellRange} testedRange
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'isEqual',
	    value: function isEqual(testedRange) {
	      return Math.min(this.from.row, this.to.row) == Math.min(testedRange.from.row, testedRange.to.row) && Math.max(this.from.row, this.to.row) == Math.max(testedRange.from.row, testedRange.to.row) && Math.min(this.from.col, this.to.col) == Math.min(testedRange.from.col, testedRange.to.col) && Math.max(this.from.col, this.to.col) == Math.max(testedRange.from.col, testedRange.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} testedRange
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'overlaps',
	    value: function overlaps(testedRange) {
	      return testedRange.isSouthEastOf(this.getTopLeftCorner()) && testedRange.isNorthWestOf(this.getBottomRightCorner());
	    }
	
	    /**
	     * @param {CellRange} testedCoords
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'isSouthEastOf',
	    value: function isSouthEastOf(testedCoords) {
	      return this.getTopLeftCorner().isSouthEastOf(testedCoords) || this.getBottomRightCorner().isSouthEastOf(testedCoords);
	    }
	
	    /**
	     * @param {CellRange} testedCoords
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'isNorthWestOf',
	    value: function isNorthWestOf(testedCoords) {
	      return this.getTopLeftCorner().isNorthWestOf(testedCoords) || this.getBottomRightCorner().isNorthWestOf(testedCoords);
	    }
	
	    /**
	     * 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 _coords2.default(Math.min(topLeft.row, cellCoords.row), Math.min(topLeft.col, cellCoords.col));
	        this.to = new _coords2.default(Math.max(bottomRight.row, cellCoords.row), Math.max(bottomRight.col, cellCoords.col));
	
	        return true;
	      }
	
	      return false;
	    }
	
	    /**
	     * @param {CellRange} expandingRange
	     * @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 topRight = this.getTopRightCorner();
	      var bottomLeft = this.getBottomLeftCorner();
	
	      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 _coords2.default(resultTopRow, resultTopCol),
	          finalTo = new _coords2.default(resultBottomRow, resultBottomCol);
	      var isCorner = new CellRange(finalFrom, finalFrom, finalTo).isCorner(this.from, expandingRange),
	          onlyMerge = expandingRange.isEqual(new CellRange(finalFrom, finalFrom, finalTo));
	
	      if (isCorner && !onlyMerge) {
	        if (this.from.col > finalFrom.col) {
	          finalFrom.col = resultBottomCol;
	          finalTo.col = resultTopCol;
	        }
	        if (this.from.row > finalFrom.row) {
	          finalFrom.row = resultBottomRow;
	          finalTo.row = resultTopRow;
	        }
	      }
	      this.from = finalFrom;
	      this.to = finalTo;
	
	      return true;
	    }
	
	    /**
	     * @returns {String}
	     */
	
	  }, {
	    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';
	      }
	    }
	
	    /**
	     * @param {String} direction
	     */
	
	  }, {
	    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;
	      }
	    }
	
	    /**
	     * Get top left corner of this range
	     *
	     * @returns {CellCoords}
	     */
	
	  }, {
	    key: 'getTopLeftCorner',
	    value: function getTopLeftCorner() {
	      return new _coords2.default(Math.min(this.from.row, this.to.row), Math.min(this.from.col, this.to.col));
	    }
	
	    /**
	     * Get bottom right corner of this range
	     *
	     * @returns {CellCoords}
	     */
	
	  }, {
	    key: 'getBottomRightCorner',
	    value: function getBottomRightCorner() {
	      return new _coords2.default(Math.max(this.from.row, this.to.row), Math.max(this.from.col, this.to.col));
	    }
	
	    /**
	     * Get top right corner of this range
	     *
	     * @returns {CellCoords}
	     */
	
	  }, {
	    key: 'getTopRightCorner',
	    value: function getTopRightCorner() {
	      return new _coords2.default(Math.min(this.from.row, this.to.row), Math.max(this.from.col, this.to.col));
	    }
	
	    /**
	     * Get bottom left corner of this range
	     *
	     * @returns {CellCoords}
	     */
	
	  }, {
	    key: 'getBottomLeftCorner',
	    value: function getBottomLeftCorner() {
	      return new _coords2.default(Math.max(this.from.row, this.to.row), Math.min(this.from.col, this.to.col));
	    }
	
	    /**
	     * @param {CellCoords} coords
	     * @param {CellRange} expandedRange
	     * @returns {*}
	     */
	
	  }, {
	    key: 'isCorner',
	    value: function isCorner(coords, expandedRange) {
	      if (expandedRange) {
	        if (expandedRange.includes(coords)) {
	          if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col)) || this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col)) || this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col)) || this.getBottomRightCorner().isEqual(new _coords2.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());
	    }
	
	    /**
	     * @param {CellCoords} coords
	     * @param {CellRange} expandedRange
	     * @returns {CellCoords}
	     */
	
	  }, {
	    key: 'getOppositeCorner',
	    value: function getOppositeCorner(coords, expandedRange) {
	      if (!(coords instanceof _coords2.default)) {
	        return false;
	      }
	
	      if (expandedRange) {
	        if (expandedRange.includes(coords)) {
	          if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col))) {
	            return this.getBottomRightCorner();
	          }
	          if (this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col))) {
	            return this.getBottomLeftCorner();
	          }
	          if (this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col))) {
	            return this.getTopRightCorner();
	          }
	          if (this.getBottomRightCorner().isEqual(new _coords2.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 _coords2.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 _coords2.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;
	          }
	        }
	      }
	    }
	  }]);
	
	  return CellRange;
	}();
	
	exports.default = CellRange;
	
	/***/ }),
	/* 80 */
	/***/ (function(module, exports) {
	
	module.exports = __WEBPACK_EXTERNAL_MODULE_80__;
	
	/***/ }),
	/* 81 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.getRegisteredCellTypes = exports.getRegisteredCellTypeNames = exports.hasCellType = exports.getCellType = exports.registerCellType = undefined;
	
	var _staticRegister2 = __webpack_require__(63);
	
	var _staticRegister3 = _interopRequireDefault(_staticRegister2);
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var _autocompleteType = __webpack_require__(231);
	
	var _autocompleteType2 = _interopRequireDefault(_autocompleteType);
	
	var _checkboxType = __webpack_require__(232);
	
	var _checkboxType2 = _interopRequireDefault(_checkboxType);
	
	var _dateType = __webpack_require__(233);
	
	var _dateType2 = _interopRequireDefault(_dateType);
	
	var _dropdownType = __webpack_require__(234);
	
	var _dropdownType2 = _interopRequireDefault(_dropdownType);
	
	var _handsontableType = __webpack_require__(235);
	
	var _handsontableType2 = _interopRequireDefault(_handsontableType);
	
	var _numericType = __webpack_require__(236);
	
	var _numericType2 = _interopRequireDefault(_numericType);
	
	var _passwordType = __webpack_require__(237);
	
	var _passwordType2 = _interopRequireDefault(_passwordType);
	
	var _textType = __webpack_require__(238);
	
	var _textType2 = _interopRequireDefault(_textType);
	
	var _timeType = __webpack_require__(239);
	
	var _timeType2 = _interopRequireDefault(_timeType);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var _staticRegister = (0, _staticRegister3.default)('cellTypes'),
	    register = _staticRegister.register,
	    getItem = _staticRegister.getItem,
	    hasItem = _staticRegister.hasItem,
	    getNames = _staticRegister.getNames,
	    getValues = _staticRegister.getValues;
	
	_register('autocomplete', _autocompleteType2.default);
	_register('checkbox', _checkboxType2.default);
	_register('date', _dateType2.default);
	_register('dropdown', _dropdownType2.default);
	_register('handsontable', _handsontableType2.default);
	_register('numeric', _numericType2.default);
	_register('password', _passwordType2.default);
	_register('text', _textType2.default);
	_register('time', _timeType2.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 "' + 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);
	}
	
	exports.registerCellType = _register;
	exports.getCellType = _getItem;
	exports.hasCellType = hasItem;
	exports.getRegisteredCellTypeNames = getNames;
	exports.getRegisteredCellTypes = getValues;
	
	/***/ }),
	/* 82 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _slicedToArray = function () { function sliceIterator(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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	exports.default = Core;
	
	var _numbro = __webpack_require__(80);
	
	var _numbro2 = _interopRequireDefault(_numbro);
	
	var _element = __webpack_require__(0);
	
	var _setting = __webpack_require__(83);
	
	var _function = __webpack_require__(35);
	
	var _mixed = __webpack_require__(22);
	
	var _browser = __webpack_require__(26);
	
	var _dataMap = __webpack_require__(240);
	
	var _dataMap2 = _interopRequireDefault(_dataMap);
	
	var _editorManager = __webpack_require__(243);
	
	var _editorManager2 = _interopRequireDefault(_editorManager);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _object = __webpack_require__(1);
	
	var _array = __webpack_require__(2);
	
	var _plugins = __webpack_require__(5);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var _string = __webpack_require__(32);
	
	var _number = __webpack_require__(6);
	
	var _tableView = __webpack_require__(244);
	
	var _tableView2 = _interopRequireDefault(_tableView);
	
	var _dataSource = __webpack_require__(245);
	
	var _dataSource2 = _interopRequireDefault(_dataSource);
	
	var _data = __webpack_require__(84);
	
	var _recordTranslator = __webpack_require__(172);
	
	var _rootInstance = __webpack_require__(173);
	
	var _src = __webpack_require__(12);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _defaultSettings = __webpack_require__(174);
	
	var _defaultSettings2 = _interopRequireDefault(_defaultSettings);
	
	var _cellTypes = __webpack_require__(81);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	var activeGuid = null;
	
	/**
	 * Handsontable constructor
	 *
	 * @core
	 * @dependencies numbro
	 * @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
	 * var ht = 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 rootInstanceSymbol = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
	
	  var priv,
	      datamap,
	      dataSource,
	      grid,
	      selection,
	      editorManager,
	      instance = this,
	      GridSettings = function GridSettings() {},
	      eventManager = new _eventManager2.default(instance);
	
	  (0, _object.extend)(GridSettings.prototype, _defaultSettings2.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));
	
	  if ((0, _rootInstance.hasValidParameter)(rootInstanceSymbol)) {
	    (0, _rootInstance.registerAsRootInstance)(this);
	  }
	
	  this.rootElement = rootElement;
	  this.isHotTableEnv = (0, _element.isChildOfWebComponentTable)(this.rootElement);
	  _eventManager2.default.isHotTableEnv = this.isHotTableEnv;
	
	  this.container = document.createElement('div');
	  this.renderCall = false;
	
	  rootElement.insertBefore(this.container, rootElement.firstChild);
	
	  if (false) {
	    (0, _mixed._injectProductInfo)(userSettings.licenseKey, rootElement);
	  }
	
	  this.guid = 'ht_' + (0, _string.randomString)(); // this is the namespace for global events
	
	  var recordTranslator = (0, _recordTranslator.getTranslator)(instance);
	
	  dataSource = new _dataSource2.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'],
	    settings: new GridSettings(), // current settings instance
	    selRange: null, // exposed by public method `getSelectedRange`
	    isPopulated: null,
	    scrollable: null,
	    firstRun: true
	  };
	
	  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} index
	     * @param {Number} amount
	     * @param {String} [source] Optional. Source of hook runner.
	     * @param {Boolean} [keepEmptyRows] Optional. Flag for preventing deletion of empty rows.
	     */
	    alter: function alter(action, index, amount, source, keepEmptyRows) {
	      var delta;
	
	      amount = amount || 1;
	
	      function spliceWith(data, index, count, toInject) {
	        var valueFactory = function valueFactory() {
	          var result = void 0;
	
	          if (toInject === 'array') {
	            result = [];
	          } else if (toInject === 'object') {
	            result = {};
	          }
	
	          return result;
	        };
	        var spliceArgs = (0, _array.arrayMap)(new Array(count), function () {
	          return valueFactory();
	        });
	
	        spliceArgs.unshift(index, 0);
	        data.splice.apply(data, _toConsumableArray(spliceArgs));
	      }
	
	      /* eslint-disable no-case-declarations */
	      switch (action) {
	        case 'insert_row':
	
	          var numberOfSourceRows = instance.countSourceRows();
	
	          if (instance.getSettings().maxRows === numberOfSourceRows) {
	            return;
	          }
	
	          index = (0, _mixed.isDefined)(index) ? index : numberOfSourceRows;
	
	          delta = datamap.createRow(index, amount, source);
	          spliceWith(priv.cellSettings, index, amount, 'array');
	
	          if (delta) {
	            if (selection.isSelected() && priv.selRange.from.row >= index) {
	              priv.selRange.from.row += delta;
	              selection.transformEnd(delta, 0); // will call render() internally
	            } else {
	              selection.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() && priv.selRange.from.col >= index) {
	              priv.selRange.from.col += delta;
	              selection.transformEnd(0, delta); // will call render() internally
	            } else {
	              selection.refreshBorders(); // it will call render and prepare methods
	            }
	          }
	          break;
	
	        case 'remove_row':
	          datamap.removeRow(index, amount, source);
	          priv.cellSettings.splice(index, amount);
	
	          var totalRows = instance.countRows();
	          var fixedRowsTop = instance.getSettings().fixedRowsTop;
	          if (fixedRowsTop >= index + 1) {
	            instance.getSettings().fixedRowsTop -= Math.min(amount, fixedRowsTop - index);
	          }
	
	          var fixedRowsBottom = instance.getSettings().fixedRowsBottom;
	          if (fixedRowsBottom && index >= totalRows - fixedRowsBottom) {
	            instance.getSettings().fixedRowsBottom -= Math.min(amount, fixedRowsBottom);
	          }
	
	          grid.adjustRowsAndCols();
	          selection.refreshBorders(); // it will call render and prepare methods
	          break;
	
	        case 'remove_col':
	          var visualColumnIndex = recordTranslator.toPhysicalColumn(index);
	
	          datamap.removeCol(index, amount, 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, amount);
	            }
	          }
	          var fixedColumnsLeft = instance.getSettings().fixedColumnsLeft;
	
	          if (fixedColumnsLeft >= index + 1) {
	            instance.getSettings().fixedColumnsLeft -= Math.min(amount, fixedColumnsLeft - index);
	          }
	
	          if (Array.isArray(instance.getSettings().colHeaders)) {
	            if (typeof visualColumnIndex === 'undefined') {
	              visualColumnIndex = -1;
	            }
	            instance.getSettings().colHeaders.splice(visualColumnIndex, amount);
	          }
	
	          grid.adjustRowsAndCols();
	          selection.refreshBorders(); // it will call render and prepare methods
	
	          break;
	        default:
	          throw new Error('There is no such action "' + 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 = void 0;
	
	        // 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()) {
	        var selectionChanged = false;
	        var fromRow = priv.selRange.from.row;
	        var fromCol = priv.selRange.from.col;
	        var toRow = priv.selRange.to.row;
	        var toCol = priv.selRange.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,
	          rlen,
	          c,
	          clen,
	          setData = [],
	          current = {};
	
	      rlen = input.length;
	
	      if (rlen === 0) {
	        return false;
	      }
	
	      var repeatCol,
	          repeatRow,
	          cmax,
	          rmax,
	          baseEnd = {
	        row: end === null ? null : end.row,
	        col: end === null ? null : end.col
	      };
	
	      /* 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;
	          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, _toConsumableArray(input[c]));
	            } else {
	              var _instance2;
	
	              input[c % clen][0] = start.col + c;
	              (_instance2 = instance).spliceCol.apply(_instance2, _toConsumableArray(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, _toConsumableArray(input[r]));
	            } else {
	              var _instance4;
	
	              input[r % rlen][0] = start.row + r;
	              (_instance4 = instance).spliceRow.apply(_instance4, _toConsumableArray(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 = void 0;
	
	          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++;
	              current.row++;
	              rlen++;
	              /* 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++;
	                current.col++;
	                clen++;
	                continue;
	              }
	              if (cellMeta.readOnly) {
	                current.col++;
	                /* 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 && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
	                if (orgValue === null || (typeof orgValue === 'undefined' ? 'undefined' : _typeof(orgValue)) !== 'object') {
	                  pushData = false;
	                } else {
	                  var orgValueSchema = (0, _object.duckSchema)(orgValue[0] || orgValue);
	                  var valueSchema = (0, _object.duckSchema)(value[0] || value);
	
	                  /* eslint-disable max-depth */
	                  if ((0, _object.isObjectEquals)(orgValueSchema, valueSchema)) {
	                    value = (0, _object.deepClone)(value);
	                  } else {
	                    pushData = false;
	                  }
	                }
	              } else if (orgValue !== null && (typeof orgValue === 'undefined' ? 'undefined' : _typeof(orgValue)) === 'object') {
	                pushData = false;
	              }
	              if (pushData) {
	                setData.push([current.row, current.col, value]);
	              }
	              pushData = true;
	              current.col++;
	            }
	            current.row++;
	          }
	          instance.setDataAtCell(setData, null, null, source || 'populateFromArray');
	          break;
	      }
	    }
	  };
	
	  /* eslint-disable no-multi-assign */
	  this.selection = selection = { // this public assignment is only temporary
	    inProgress: false,
	
	    selectedHeader: {
	      cols: false,
	      rows: false
	    },
	
	    /**
	     * @param {Boolean} [rows=false]
	     * @param {Boolean} [cols=false]
	     * @param {Boolean} [corner=false]
	     */
	    setSelectedHeaders: function setSelectedHeaders() {
	      var rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
	      var cols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
	      var corner = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
	
	      instance.selection.selectedHeader.rows = rows;
	      instance.selection.selectedHeader.cols = cols;
	      instance.selection.selectedHeader.corner = corner;
	    },
	
	
	    /**
	     * Sets inProgress to `true`. This enables onSelectionEnd and onSelectionEndByProp to function as desired.
	     */
	    begin: function begin() {
	      instance.selection.inProgress = true;
	    },
	
	
	    /**
	     * Sets inProgress to `false`. Triggers onSelectionEnd and onSelectionEndByProp.
	     */
	    finish: function finish() {
	      var sel = instance.getSelected();
	      instance.runHooks('afterSelectionEnd', sel[0], sel[1], sel[2], sel[3]);
	      instance.runHooks('afterSelectionEndByProp', sel[0], instance.colToProp(sel[1]), sel[2], instance.colToProp(sel[3]));
	      instance.selection.inProgress = false;
	    },
	
	
	    /**
	     * @returns {Boolean}
	     */
	    isInProgress: function isInProgress() {
	      return instance.selection.inProgress;
	    },
	
	
	    /**
	     * Starts selection range on given td object.
	     *
	     * @param {CellCoords} coords Visual coords.
	     * @param keepEditorOpened
	     */
	    setRangeStart: function setRangeStart(coords, keepEditorOpened) {
	      instance.runHooks('beforeSetRangeStart', coords);
	      priv.selRange = new _src.CellRange(coords, coords, coords);
	      selection.setRangeEnd(coords, null, keepEditorOpened);
	    },
	
	
	    /**
	     * Starts selection range on given td object.
	     *
	     * @param {CellCoords} coords Visual coords.
	     * @param keepEditorOpened
	     */
	    setRangeStartOnly: function setRangeStartOnly(coords) {
	      instance.runHooks('beforeSetRangeStartOnly', coords);
	      priv.selRange = new _src.CellRange(coords, coords, coords);
	    },
	
	
	    /**
	     * Ends selection range on given td object.
	     *
	     * @param {CellCoords} coords Visual coords.
	     * @param {Boolean} [scrollToCell=true] If `true`, viewport will be scrolled to range end
	     * @param {Boolean} [keepEditorOpened] If `true`, cell editor will be still opened after changing selection range
	     */
	    setRangeEnd: function setRangeEnd(coords, scrollToCell, keepEditorOpened) {
	      if (priv.selRange === null) {
	        return;
	      }
	      var disableVisualSelection,
	          isHeaderSelected = false,
	          areCoordsPositive = true;
	
	      var firstVisibleRow = instance.view.wt.wtTable.getFirstVisibleRow();
	      var firstVisibleColumn = instance.view.wt.wtTable.getFirstVisibleColumn();
	      var newRangeCoords = {
	        row: null,
	        col: null
	      };
	
	      // trigger handlers
	      instance.runHooks('beforeSetRangeEnd', coords);
	      instance.selection.begin();
	
	      newRangeCoords.row = coords.row < 0 ? firstVisibleRow : coords.row;
	      newRangeCoords.col = coords.col < 0 ? firstVisibleColumn : coords.col;
	
	      priv.selRange.to = new _src.CellCoords(newRangeCoords.row, newRangeCoords.col);
	
	      if (!priv.settings.multiSelect) {
	        priv.selRange.from = coords;
	      }
	      // set up current selection
	      instance.view.wt.selections.current.clear();
	
	      disableVisualSelection = instance.getCellMeta(priv.selRange.highlight.row, priv.selRange.highlight.col).disableVisualSelection;
	
	      if (typeof disableVisualSelection === 'string') {
	        disableVisualSelection = [disableVisualSelection];
	      }
	
	      if (disableVisualSelection === false || Array.isArray(disableVisualSelection) && disableVisualSelection.indexOf('current') === -1) {
	        instance.view.wt.selections.current.add(priv.selRange.highlight);
	      }
	      // set up area selection
	      instance.view.wt.selections.area.clear();
	
	      if ((disableVisualSelection === false || Array.isArray(disableVisualSelection) && disableVisualSelection.indexOf('area') === -1) && selection.isMultiple()) {
	        instance.view.wt.selections.area.add(priv.selRange.from);
	        instance.view.wt.selections.area.add(priv.selRange.to);
	      }
	      // set up highlight
	      if (priv.settings.currentHeaderClassName || priv.settings.currentRowClassName || priv.settings.currentColClassName) {
	        instance.view.wt.selections.highlight.clear();
	        instance.view.wt.selections.highlight.add(priv.selRange.from);
	        instance.view.wt.selections.highlight.add(priv.selRange.to);
	      }
	
	      var preventScrolling = (0, _object.createObjectPropListener)('value');
	
	      // trigger handlers
	      instance.runHooks('afterSelection', priv.selRange.from.row, priv.selRange.from.col, priv.selRange.to.row, priv.selRange.to.col, preventScrolling);
	      instance.runHooks('afterSelectionByProp', priv.selRange.from.row, datamap.colToProp(priv.selRange.from.col), priv.selRange.to.row, datamap.colToProp(priv.selRange.to.col), preventScrolling);
	
	      if (priv.selRange.from.row === 0 && priv.selRange.to.row === instance.countRows() - 1 && instance.countRows() > 1 || priv.selRange.from.col === 0 && priv.selRange.to.col === instance.countCols() - 1 && instance.countCols() > 1) {
	        isHeaderSelected = true;
	      }
	
	      if (coords.row < 0 || coords.col < 0) {
	        areCoordsPositive = false;
	      }
	
	      if (preventScrolling.isTouched()) {
	        scrollToCell = !preventScrolling.value;
	      }
	
	      if (scrollToCell !== false && !isHeaderSelected && areCoordsPositive) {
	        if (priv.selRange.from && !selection.isMultiple()) {
	          instance.view.scrollViewport(priv.selRange.from);
	        } else {
	          instance.view.scrollViewport(coords);
	        }
	      }
	
	      if (selection.selectedHeader.rows && selection.selectedHeader.cols) {
	        (0, _element.addClass)(instance.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
	      } else if (selection.selectedHeader.rows) {
	        (0, _element.removeClass)(instance.rootElement, 'ht__selection--columns');
	        (0, _element.addClass)(instance.rootElement, 'ht__selection--rows');
	      } else if (selection.selectedHeader.cols) {
	        (0, _element.removeClass)(instance.rootElement, 'ht__selection--rows');
	        (0, _element.addClass)(instance.rootElement, 'ht__selection--columns');
	      } else {
	        (0, _element.removeClass)(instance.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
	      }
	
	      selection.refreshBorders(null, keepEditorOpened);
	    },
	
	
	    /**
	     * Destroys editor, redraws borders around cells, prepares editor.
	     *
	     * @param {Boolean} [revertOriginal]
	     * @param {Boolean} [keepEditor]
	     */
	    refreshBorders: function refreshBorders(revertOriginal, keepEditor) {
	      if (!keepEditor) {
	        editorManager.destroyEditor(revertOriginal);
	      }
	      instance.view.render();
	
	      if (selection.isSelected() && !keepEditor) {
	        editorManager.prepareEditor();
	      }
	    },
	
	
	    /**
	     * Returns information if we have a multiselection.
	     *
	     * @returns {Boolean}
	     */
	    isMultiple: function isMultiple() {
	      var isMultiple = !(priv.selRange.to.col === priv.selRange.from.col && priv.selRange.to.row === priv.selRange.from.row),
	          modifier = instance.runHooks('afterIsMultipleSelection', isMultiple);
	
	      if (isMultiple) {
	        return modifier;
	      }
	    },
	
	
	    /**
	     * Selects cell relative to current cell (if possible).
	     */
	    transformStart: function transformStart(rowDelta, colDelta, force, keepEditorOpened) {
	      var delta = new _src.CellCoords(rowDelta, colDelta),
	          rowTransformDir = 0,
	          colTransformDir = 0,
	          totalRows,
	          totalCols,
	          coords,
	          fixedRowsBottom;
	
	      instance.runHooks('modifyTransformStart', delta);
	      totalRows = instance.countRows();
	      totalCols = instance.countCols();
	      fixedRowsBottom = instance.getSettings().fixedRowsBottom;
	
	      if (priv.selRange.highlight.row + rowDelta > totalRows - 1) {
	        if (force && priv.settings.minSpareRows > 0 && !(fixedRowsBottom && priv.selRange.highlight.row >= totalRows - fixedRowsBottom - 1)) {
	          instance.alter('insert_row', totalRows);
	          totalRows = instance.countRows();
	        } else if (priv.settings.autoWrapCol) {
	          delta.row = 1 - totalRows;
	          delta.col = priv.selRange.highlight.col + delta.col == totalCols - 1 ? 1 - totalCols : 1;
	        }
	      } else if (priv.settings.autoWrapCol && priv.selRange.highlight.row + delta.row < 0 && priv.selRange.highlight.col + delta.col >= 0) {
	        delta.row = totalRows - 1;
	        delta.col = priv.selRange.highlight.col + delta.col == 0 ? totalCols - 1 : -1;
	      }
	
	      if (priv.selRange.highlight.col + delta.col > totalCols - 1) {
	        if (force && priv.settings.minSpareCols > 0) {
	          instance.alter('insert_col', totalCols);
	          totalCols = instance.countCols();
	        } else if (priv.settings.autoWrapRow) {
	          delta.row = priv.selRange.highlight.row + delta.row == totalRows - 1 ? 1 - totalRows : 1;
	          delta.col = 1 - totalCols;
	        }
	      } else if (priv.settings.autoWrapRow && priv.selRange.highlight.col + delta.col < 0 && priv.selRange.highlight.row + delta.row >= 0) {
	        delta.row = priv.selRange.highlight.row + delta.row == 0 ? totalRows - 1 : -1;
	        delta.col = totalCols - 1;
	      }
	
	      coords = new _src.CellCoords(priv.selRange.highlight.row + delta.row, priv.selRange.highlight.col + delta.col);
	
	      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;
	      }
	      instance.runHooks('afterModifyTransformStart', coords, rowTransformDir, colTransformDir);
	      selection.setRangeStart(coords, keepEditorOpened);
	    },
	
	
	    /**
	     * Sets selection end cell relative to current selection end cell (if possible).
	     */
	    transformEnd: function transformEnd(rowDelta, colDelta) {
	      var delta = new _src.CellCoords(rowDelta, colDelta),
	          rowTransformDir = 0,
	          colTransformDir = 0,
	          totalRows,
	          totalCols,
	          coords;
	
	      instance.runHooks('modifyTransformEnd', delta);
	
	      totalRows = instance.countRows();
	      totalCols = instance.countCols();
	      coords = new _src.CellCoords(priv.selRange.to.row + delta.row, priv.selRange.to.col + delta.col);
	
	      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;
	      }
	      instance.runHooks('afterModifyTransformEnd', coords, rowTransformDir, colTransformDir);
	      selection.setRangeEnd(coords, true);
	    },
	
	
	    /**
	     * Returns `true` if currently there is a selection on screen, `false` otherwise.
	     *
	     * @returns {Boolean}
	     */
	    isSelected: function isSelected() {
	      return priv.selRange !== null;
	    },
	
	
	    /**
	     * Returns `true` if coords is within current selection coords.
	     *
	     * @param {CellCoords} coords
	     * @returns {Boolean}
	     */
	    inInSelection: function inInSelection(coords) {
	      if (!selection.isSelected()) {
	        return false;
	      }
	
	      return priv.selRange.includes(coords);
	    },
	
	
	    /**
	     * Deselects all selected cells
	     */
	    deselect: function deselect() {
	      if (!selection.isSelected()) {
	        return;
	      }
	      instance.selection.inProgress = false; // needed by HT inception
	      priv.selRange = null;
	      instance.view.wt.selections.current.clear();
	      instance.view.wt.selections.area.clear();
	      if (priv.settings.currentHeaderClassName || priv.settings.currentRowClassName || priv.settings.currentColClassName) {
	        instance.view.wt.selections.highlight.clear();
	      }
	      editorManager.destroyEditor();
	      selection.refreshBorders();
	      (0, _element.removeClass)(instance.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
	      instance.runHooks('afterDeselect');
	    },
	
	
	    /**
	     * Select all cells
	     */
	    selectAll: function selectAll() {
	      if (!priv.settings.multiSelect) {
	        return;
	      }
	      selection.setSelectedHeaders(true, true, true);
	      selection.setRangeStart(new _src.CellCoords(0, 0));
	      selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, instance.countCols() - 1), false);
	    },
	
	
	    /**
	     * Deletes data from selected cells
	     */
	    empty: function empty() {
	      if (!selection.isSelected()) {
	        return;
	      }
	      var topLeft = priv.selRange.getTopLeftCorner();
	      var bottomRight = priv.selRange.getBottomRightCorner();
	      var r,
	          c,
	          changes = [];
	
	      for (r = topLeft.row; r <= bottomRight.row; r++) {
	        for (c = topLeft.col; c <= bottomRight.col; c++) {
	          if (!instance.getCellMeta(r, c).readOnly) {
	            changes.push([r, c, '']);
	          }
	        }
	      }
	      instance.setDataAtCell(changes);
	    }
	  };
	
	  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 _tableView2.default(this);
	    editorManager = new _editorManager2.default(instance, priv, selection, datamap);
	
	    this.forceFullRender = true; // used when data was changed
	
	    instance.runHooks('init');
	    this.view.render();
	
	    if (_typeof(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++;
	        resolved = false;
	      },
	      removeValidatorFormQueue: function removeValidatorFormQueue() {
	        this.validatorsInQueue = this.validatorsInQueue - 1 < 0 ? 0 : this.validatorsInQueue - 1;
	        this.checkIfQueueIsEmpty();
	      },
	      onQueueEmpty: function onQueueEmpty(valid) {},
	      checkIfQueueIsEmpty: function checkIfQueueIsEmpty() {
	        if (this.validatorsInQueue == 0 && resolved == false) {
	          resolved = true;
	          this.onQueueEmpty(this.valid);
	        }
	      }
	    };
	  }
	
	  function validateChanges(changes, source, callback) {
	    var waitingForValidator = new ValidatorsQueue();
	    waitingForValidator.onQueueEmpty = resolve;
	
	    for (var i = changes.length - 1; i >= 0; i--) {
	      if (changes[i] === null) {
	        changes.splice(i, 1);
	      } else {
	        var row = changes[i][0];
	        var col = datamap.propToCol(changes[i][1]);
	
	        var cellProperties = instance.getCellMeta(row, col);
	
	        if (cellProperties.type === 'numeric' && typeof changes[i][3] === 'string') {
	          if (changes[i][3].length > 0 && (/^-?[\d\s]*(\.|,)?\d*$/.test(changes[i][3]) || cellProperties.format)) {
	            var len = changes[i][3].length;
	
	            if ((0, _mixed.isUndefined)(cellProperties.language)) {
	              _numbro2.default.culture('en-US');
	            } else if (changes[i][3].indexOf('.') === len - 3 && changes[i][3].indexOf(',') === -1) {
	              // this input in format XXXX.XX is likely to come from paste. Let's parse it using international rules
	              _numbro2.default.culture('en-US');
	            } else {
	
	              _numbro2.default.culture(cellProperties.language);
	            }
	
	            var _numbro$cultureData = _numbro2.default.cultureData(_numbro2.default.culture()),
	                delimiters = _numbro$cultureData.delimiters;
	
	            // try to parse to float - https://github.com/foretagsplatsen/numbro/pull/183
	
	
	            if (_numbro2.default.validate(changes[i][3]) && !isNaN(changes[i][3])) {
	              changes[i][3] = parseFloat(changes[i][3]);
	            } else {
	              changes[i][3] = (0, _numbro2.default)().unformat(changes[i][3]) || changes[i][3];
	            }
	          }
	        }
	
	        /* eslint-disable no-loop-func */
	        if (instance.getCellValidator(cellProperties)) {
	          waitingForValidator.addValidatorToQueue();
	          instance.validateCell(changes[i][3], cellProperties, function (i, cellProperties) {
	            return function (result) {
	              if (typeof result !== 'boolean') {
	                throw new Error('Validation error: result is not boolean');
	              }
	              if (result === false && cellProperties.allowInvalid === false) {
	                changes.splice(i, 1); // cancel the change
	                cellProperties.valid = true; // we cancelled the change, so cell value is still valid
	                var cell = instance.getCell(cellProperties.visualRow, cellProperties.visualCol);
	                (0, _element.removeClass)(cell, instance.getSettings().invalidCellClassName);
	                --i;
	              }
	              waitingForValidator.removeValidatorFormQueue();
	            };
	          }(i, cellProperties), source);
	        }
	      }
	    }
	    waitingForValidator.checkIfQueueIsEmpty();
	
	    function resolve() {
	      var beforeChangeResult;
	
	      if (changes.length) {
	        beforeChangeResult = instance.runHooks('beforeChange', changes, source);
	        if ((0, _function.isFunction)(beforeChangeResult)) {
	          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) {
	          changes.splice(0, changes.length); // invalidate all changes (remove everything from array)
	        }
	      }
	      callback(); // called when async validators are resolved and beforeChange was not async
	    }
	  }
	
	  /**
	   * 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][3] == null) {
	        /* 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);
	    selection.refreshBorders(null, true);
	    instance.view.wt.wtOverlays.adjustElementsSize();
	    instance.runHooks('afterChange', changes, source || 'edit');
	
	    var activeEditor = instance.getActiveEditor();
	
	    if (activeEditor && (0, _mixed.isDefined)(activeEditor.refreshValue)) {
	      activeEditor.refreshValue();
	    }
	  }
	
	  this.validateCell = function (value, cellProperties, callback, source) {
	    var validator = instance.getCellValidator(cellProperties);
	
	    function done(valid) {
	      var col = cellProperties.visualCol,
	          row = cellProperties.visualRow,
	          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 (validator) {
	        return function (value, callback) {
	          callback(validator.test(value));
	        };
	      }(validator);
	    }
	
	    if ((0, _function.isFunction)(validator)) {
	
	      value = instance.runHooks('beforeValidate', value, cellProperties.visualRow, cellProperties.prop, source);
	
	      // To provide consistent behaviour, validation should be always asynchronous
	      instance._registerTimeout(setTimeout(function () {
	        validator.call(cellProperties, value, function (valid) {
	          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);
	        });
	      }, 0));
	    } else {
	      // resolve callback even if validator function was not found
	      instance._registerTimeout(setTimeout(function () {
	        cellProperties.valid = true;
	        done(cellProperties.valid);
	      }, 0));
	    }
	  };
	
	  function setDataInputToArray(row, propOrCol, value) {
	    if ((typeof row === 'undefined' ? 'undefined' : _typeof(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, pass an array of `changes` in format `[[row, col, value], ...]` as
	   * the only parameter. `col` is the index of a __visible__ column (note that if columns were reordered,
	   * the current visible order will be used). `source` is a flag for before/afterChange events. If you pass only array of
	   * changes then `source` could be set as second parameter.
	   *
	   * @memberof Core#
	   * @function setDataAtCell
	   * @param {Number|Array} row Visual row index or array of changes in format `[[row, col, value], ...]`.
	   * @param {Number} col 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, col, value, source) {
	    var input = setDataInputToArray(row, col, value),
	        i,
	        ilen,
	        changes = [],
	        prop;
	
	    for (i = 0, ilen = input.length; i < ilen; i++) {
	      if (_typeof(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 (!source && (typeof row === 'undefined' ? 'undefined' : _typeof(row)) === 'object') {
	      source = col;
	    }
	
	    instance.runHooks('afterSetDataAtCell', changes, source);
	
	    validateChanges(changes, source, function () {
	      applyChanges(changes, source);
	    });
	  };
	
	  /**
	   * @description
	   * Set new value to a cell. To change many cells at once, pass an array of `changes` in format `[[row, prop, value], ...]` as
	   * the only parameter. `prop` is the name of the object property (e.g. `first.name`). `source` is a flag for before/afterChange events.
	   * If you pass only array of changes then `source` could be set as second parameter.
	   *
	   * @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.
	   * @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),
	        i,
	        ilen,
	        changes = [];
	
	    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 (!source && (typeof row === 'undefined' ? 'undefined' : _typeof(row)) === 'object') {
	      source = prop;
	    }
	
	    instance.runHooks('afterSetDataAtRowProp', changes, source);
	
	    validateChanges(changes, source, function () {
	      applyChanges(changes, source);
	    });
	  };
	
	  /**
	   * Listen to the keyboard input on document body.
	   *
	   * @memberof Core#
	   * @function listen
	   * @since 0.11
	   */
	  this.listen = function () {
	    var invalidActiveElement = !document.activeElement || document.activeElement && document.activeElement.nodeName === void 0;
	
	    if (document.activeElement && document.activeElement !== document.body && !invalidActiveElement) {
	      document.activeElement.blur();
	    } else if (invalidActiveElement) {
	      // IE
	      document.body.focus();
	    }
	
	    if (instance && !instance.isListening()) {
	      activeGuid = instance.guid;
	      instance.runHooks('afterListen');
	    }
	  };
	
	  /**
	   * Stop listening to keyboard input on the document body.
	   *
	   * @memberof Core#
	   * @function unlisten
	   * @since 0.11
	   */
	  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
	   * @since 0.11
	   * @returns {Boolean} `true` if the instance is listening, `false` otherwise.
	   */
	  this.isListening = function () {
	    return activeGuid === instance.guid;
	  };
	
	  /**
	   * Destroys the current editor, renders and selects the current cell.
	   *
	   * @memberof Core#
	   * @function destroyEditor
	   * @param {Boolean} [revertOriginal] If != `true`, edited data is saved. Otherwise the previous value is restored.
	   */
	  this.destroyEditor = function (revertOriginal) {
	    selection.refreshBorders(revertOriginal);
	  };
	
	  /**
	   * 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 `source` parameter (default value "populateFromArray") is used to identify this call in the resulting events (beforeChange, afterChange).
	   * Optional `populateMethod` parameter (default value "overwrite", possible values "shift_down" and "shift_right")
	   * has the same effect as pasteMode option {@link Options#pasteMode}
	   *
	   * @memberof Core#
	   * @function populateFromArray
	   * @since 0.9.0
	   * @param {Number} row Start visual row index.
	   * @param {Number} col 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"] Source string.
	   * @param {String} [method="overwrite"] Populate method. Possible options: `shift_down`, `shift_right`, `overwrite`.
	   * @param {String} direction Populate direction. (left|right|up|down)
	   * @param {Array} deltas Deltas array.
	   * @returns {Object|undefined} The ending TD element in pasted area (only if any cells were changed).
	   */
	  this.populateFromArray = function (row, col, input, endRow, endCol, source, method, direction, deltas) {
	    var c;
	
	    if (!((typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object' && _typeof(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
	    }
	    c = typeof endRow === 'number' ? new _src.CellCoords(endRow, endCol) : null;
	
	    return grid.populateFromArray(new _src.CellCoords(row, col), input, c, source, method, direction, deltas);
	  };
	
	  /**
	   * Adds/removes data from the column. This function is modelled after Array.splice.
	   * Parameter `col` is the index of the column in which do you want to do splice.
	   * Parameter `index` is the row index at which to start changing the array.
	   * If negative, will begin that many elements from the end. Parameter `amount`, is the number of the old array elements to remove.
	   * If the amount is 0, no elements are removed. Fourth and further parameters are the `elements` to add to the array.
	   * If you don't specify any elements, spliceCol simply removes elements from the array.
	   * {@link DataMap#spliceCol}
	   *
	   * @memberof Core#
	   * @function spliceCol
	   * @since 0.9-beta2
	   * @param {Number} col 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 {*} [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 (col, index, amount /* , elements... */) {
	    var _datamap;
	
	    return (_datamap = datamap).spliceCol.apply(_datamap, arguments);
	  };
	
	  /**
	   * Adds/removes data from the row. This function works is modelled after Array.splice.
	   * Parameter `row` is the index of row in which do you want to do splice.
	   * Parameter `index` is the column index at which to start changing the array.
	   * If negative, will begin that many elements from the end. Parameter `amount`, is the number of old array elements to remove.
	   * If the amount is 0, no elements are removed. Fourth and further parameters are the `elements` to add to the array.
	   * If you don't specify any elements, spliceCol simply removes elements from the array.
	   * {@link DataMap#spliceRow}
	   *
	   * @memberof Core#
	   * @function spliceRow
	   * @since 0.11
	   * @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 {*} [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 /* , elements... */) {
	    var _datamap2;
	
	    return (_datamap2 = datamap).spliceRow.apply(_datamap2, arguments);
	  };
	
	  /**
	   * Returns indexes of the currently selected cells as an array `[startRow, startCol, endRow, endCol]`.
	   *
	   * Start row and start col are the coordinates of the active cell (where the selection was started).
	   *
	   * @memberof Core#
	   * @function getSelected
	   * @returns {Array} Array of the selection's indexes.
	   */
	  this.getSelected = function () {
	    // https://github.com/handsontable/handsontable/issues/44  //cjl
	    if (selection.isSelected()) {
	      return [priv.selRange.from.row, priv.selRange.from.col, priv.selRange.to.row, priv.selRange.to.col];
	    }
	  };
	
	  /**
	   * Returns the current selection as a CellRange object.
	   *
	   * @memberof Core#
	   * @function getSelectedRange
	   * @since 0.11
	   * @returns {CellRange} 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 priv.selRange;
	    }
	  };
	
	  /**
	   * Rerender the table.
	   *
	   * @memberof Core#
	   * @function render
	   */
	  this.render = function () {
	    if (instance.view) {
	      instance.renderCall = true;
	      instance.forceFullRender = true; // used when data was changed
	      selection.refreshBorders(null, true);
	    }
	  };
	
	  /**
	   * Reset all cells in the grid to contain data from the data array.
	   *
	   * @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 _dataMap2.default(instance, priv, GridSettings);
	
	    if ((typeof data === 'undefined' ? 'undefined' : _typeof(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
	        data = [data];
	      }
	    } else if (data === null) {
	      data = [];
	      var row;
	      var r = 0;
	      var rlen = 0;
	      var dataSchema = datamap.getSchema();
	
	      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 (' + (typeof data === 'undefined' ? 'undefined' : _typeof(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`, `col`, `row2`, `col2` to get only a fragment of grid data.
	   *
	   * Note: getData functionality changed with the release of version 0.20. If you're looking for the previous functionality,
	   * you should use the {@link Core#getSourceData} method.
	   *
	   * @memberof Core#
	   * @function getData
	   * @param {Number} [r] From visual row index.
	   * @param {Number} [c] From visual column index.
	   * @param {Number} [r2] To visual row index.
	   * @param {Number} [c2] To visual column index.
	   * @returns {Array} Array with the data.
	   */
	  this.getData = function (r, c, r2, c2) {
	    if ((0, _mixed.isUndefined)(r)) {
	      return datamap.getAll();
	    }
	    return datamap.getRange(new _src.CellCoords(r, c), new _src.CellCoords(r2, c2), 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.
	   * {@link DataMap#getCopyableText}
	   *
	   * @memberof Core#
	   * @function getCopyableText
	   * @since 0.11
	   * @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 ({@link DataMap#getCopyable}).
	   *
	   * @memberof Core#
	   * @function getCopyableData
	   * @since 0.19.0
	   * @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
	   * @since 0.13.2
	   * @returns {Object} Schema object.
	   */
	  this.getSchema = function () {
	    return datamap.getSchema();
	  };
	
	  /**
	   * Use it if you need to change configuration after initialization. The `settings` parameter 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.
	   * @param {Boolean} init Calls this method in the initialization mode. Internal use only.
	   *                       Used by API could be cause of the unexpected behaviour of the Handsontable.
	   * @example
	   * ```js
	   * hot.updateSettings({
	   *    contextMenu: true,
	   *    colHeaders: true,
	   *    fixedRowsTop: 2
	   * });
	   * ```
	   * @fires Hooks#afterCellMetaReset
	   * @fires Hooks#afterUpdateSettings
	   */
	  this.updateSettings = function (settings, init) {
	    var columnsAsFunc = false;
	    var i = void 0;
	    var j = void 0;
	    var clen = void 0;
	
	    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?');
	    }
	
	    for (i in settings) {
	      if (i === 'data') {
	        /* eslint-disable no-continue */
	        continue; // loadData will be triggered later
	      } else if (_pluginHooks2.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 = void 0;
	      var column = void 0;
	
	      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++;
	      }
	    }
	
	    if ((0, _mixed.isDefined)(settings.cell)) {
	      for (var key in settings.cell) {
	        if ((0, _object.hasOwnProperty)(settings.cell, key)) {
	          var cell = settings.cell[key];
	
	          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 = 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 = 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
	      selection.refreshBorders(null, true);
	    }
	
	    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
	   * @since 0.11
	   * @returns {*} Value of selected cell.
	   */
	  this.getValue = function () {
	    var sel = instance.getSelected();
	    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]][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 type,
	        expandedType = {};
	
	    if (_typeof(obj.type) === 'object') {
	      type = obj.type;
	    } else if (typeof obj.type === 'string') {
	      type = (0, _cellTypes.getCellType)(obj.type);
	    }
	
	    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 grid settings.
	   */
	  this.getSettings = function () {
	    return priv.settings;
	  };
	
	  /**
	   * Clears the data from the grid. (The table settings remain intact.)
	   *
	   * @memberof Core#
	   * @function clear
	   * @since 0.11
	   */
	  this.clear = function () {
	    selection.selectAll();
	    selection.empty();
	  };
	
	  /**
	   * @memberof Core#
	   * @function alter
	   * @param {String} action See grid.alter for possible values: `"insert_row"`, `"insert_col"`, `"remove_row"`, `"remove_col"`
	   * @param {Number} index Visual index of the row/column before which the new row/column will be inserted/removed.
	   * @param {Number} [amount = 1] Amound of rows/columns to be inserted/removed.
	   * @param {String} [source] Source indicator.
	   * @param {Boolean} [keepEmptyRows] Flag for preventing deletion of empty rows.
	   * @description
	   *
	   * Allows altering the table structure by either inserting/removing rows or inserting/removing columns:
	   *
	   * Insert new row(s) above the row with a given `index`. If index is `null` or `undefined`, the new row will be
	   * added after the last row.
	   * ```js
	   * var hot = new Handsontable(document.getElementById('example'));
	   * hot.alter('insert_row', 10);
	   * ```
	   *
	   * Insert new column(s) before the column with a given `index`. If index is `null` or `undefined`, the new column
	   * will be added after the last column.
	   * ```js
	   * var hot = new Handsontable(document.getElementById('example'));
	   * hot.alter('insert_col', 10);
	   * ```
	   *
	   * Remove the row(s) at the given `index`.
	   * ```js
	   * var hot = new Handsontable(document.getElementById('example'));
	   * hot.alter('remove_row', 10);
	   * ```
	   *
	   * Remove the column(s) at the given `index`.
	   * ```js
	   * var hot = new Handsontable(document.getElementById('example'));
	   * hot.alter('remove_col', 10);
	   * ```
	   */
	  this.alter = function (action, index, amount, source, keepEmptyRows) {
	    grid.alter(action, index, amount, source, keepEmptyRows);
	  };
	
	  /**
	   * Returns a TD element for the given `row` and `col` 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} col 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.
	   * @returns {Element} The cell's TD element.
	   */
	  this.getCell = function (row, col, topmost) {
	    return instance.view.getCellAtCoords(new _src.CellCoords(row, col), topmost);
	  };
	
	  /**
	   * Returns the coordinates of the cell, provided as a HTML Element.
	   *
	   * @memberof Core#
	   * @function getCoords
	   * @param {Element} elem The HTML Element representing the cell.
	   * @returns {CellCoords} Visual coordinates object.
	   */
	  this.getCoords = function (elem) {
	    return this.view.wt.wtTable.getCoords.call(this.view.wt.wtTable, elem);
	  };
	
	  /**
	   * Returns the property name that corresponds with the given column index. {@link DataMap#colToProp}
	   * If the data source is an array of arrays, it returns the columns index.
	   *
	   * @memberof Core#
	   * @function colToProp
	   * @param {Number} col Visual column index.
	   * @returns {String|Number} Column property or physical column index.
	   */
	  this.colToProp = function (col) {
	    return datamap.colToProp(col);
	  };
	
	  /**
	   * Returns column index that corresponds with the given property. {@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.
	   *
	   * @since 0.29.0
	   * @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.
	   *
	   * @since 0.29.0
	   * @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.
	   * If displayed rows order is different than the order of rows stored in memory (i.e. sorting is applied)
	   * to retrieve valid physical row index you can use this method.
	   *
	   * @since 0.29.0
	   * @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.
	   * If displayed columns order is different than the order of columns stored in memory (i.e. manual column move is applied)
	   * to retrieve valid physical column index you can use this method.
	   *
	   * @since 0.29.0
	   * @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`, `col`. `row` and `col` are the __visible__ indexes (note, that if columns were reordered or sorted,
	   * the currently visible order will be used).
	   *
	   * @memberof Core#
	   * @function getDataAtCell
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @returns {String|Boolean|null} Data at cell.
	   */
	  this.getDataAtCell = function (row, col) {
	    return datamap.get(row, datamap.colToProp(col));
	  };
	
	  /**
	   * Return value at `row`, `prop`. (Uses {@link DataMap#get})
	   *
	   * @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. `col` is the __visible__ index of the column.
	   * Note, that if columns were reordered or sorted, the currently visible order will be used.
	   *
	   * @memberof Core#
	   * @function getDataAtCol
	   * @since 0.9-beta2
	   * @param {Number} col Visual column index.
	   * @returns {Array} Array of cell values.
	   */
	  this.getDataAtCol = function (col) {
	    var out = [];
	    return out.concat.apply(out, _toConsumableArray(datamap.getRange(new _src.CellCoords(0, col), new _src.CellCoords(priv.settings.data.length - 1, col), datamap.DESTINATION_RENDERER)));
	  };
	
	  /**
	   * Given the object property name (e.g. `'first.name'`), returns an array of column's values from the data source.
	   * You can also provide a column index as the first argument.
	   *
	   * @memberof Core#
	   * @function getDataAtProp
	   * @since 0.9-beta2
	   * @param {String|Number} prop Property name / physical column index.
	   * @returns {Array} Array of cell values.
	   */
	  // TODO: Getting data from `datamap` should work on visual indexes.
	  this.getDataAtProp = function (prop) {
	    var out = [],
	        range;
	
	    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 out.concat.apply(out, _toConsumableArray(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`, `col`, `row2`, `col2` arguments, to get only a fragment of grid data.
	   *
	   * @memberof Core#
	   * @function getSourceData
	   * @since 0.20.0
	   * @param {Number} [r] From physical row index.
	   * @param {Number} [c] From physical column index (or visual index, if data type is an array of objects).
	   * @param {Number} [r2] To physical row index.
	   * @param {Number} [c2] To physical column index (or visual index, if data type is an array of objects).
	   * @returns {Array} Array of grid data.
	   */
	  this.getSourceData = function (r, c, r2, c2) {
	    var data = void 0;
	
	    if (r === void 0) {
	      data = dataSource.getData();
	    } else {
	      data = dataSource.getByRange(new _src.CellCoords(r, c), new _src.CellCoords(r2, c2));
	    }
	
	    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`, `col`, `row2`, `col2` arguments, to get only a fragment of grid data.
	   *
	   * @memberof Core#
	   * @function getSourceDataArray
	   * @since 0.28.0
	   * @param {Number} [r] From physical row index.
	   * @param {Number} [c] From physical column index (or visual index, if data type is an array of objects).
	   * @param {Number} [r2] To physical row index.
	   * @param {Number} [c2] To physical column index (or visual index, if data type is an array of objects).
	   * @returns {Array} An array of arrays.
	   */
	  this.getSourceDataArray = function (r, c, r2, c2) {
	    var data = void 0;
	
	    if (r === void 0) {
	      data = dataSource.getData(true);
	    } else {
	      data = dataSource.getByRange(new _src.CellCoords(r, c), new _src.CellCoords(r2, c2), true);
	    }
	
	    return data;
	  };
	
	  /**
	   * Returns an array of column values from the data source. `col` is the index of the row in the data source.
	   *
	   * @memberof Core#
	   * @function getSourceDataAtCol
	   * @since 0.11.0-beta3
	   * @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 you have). `row` is the index of the row in the data source.
	   *
	   * @memberof Core#
	   * @function getSourceDataAtRow
	   * @since 0.11.0-beta3
	   * @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.
	   * @since 0.20.0
	   */
	  // 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. The `row` argument is the __visible__ index of the row.
	   *
	   * @memberof Core#
	   * @function getDataAtRow
	   * @param {Number} row Visual row index.
	   * @returns {Array} Array of row's cell data.
	   * @since 0.9-beta2
	   */
	  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'`.
	   *
	   * @since 0.18.1
	   * @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 _this = this;
	
	    var previousType = null;
	    var currentType = null;
	
	    if (rowFrom === void 0) {
	      rowFrom = 0;
	      rowTo = this.countRows();
	      columnFrom = 0;
	      columnTo = this.countCols();
	    }
	    if (rowTo === void 0) {
	      rowTo = rowFrom;
	    }
	    if (columnTo === void 0) {
	      columnTo = columnFrom;
	    }
	    var type = 'mixed';
	
	    (0, _number.rangeEach)(Math.min(rowFrom, rowTo), Math.max(rowFrom, rowTo), function (row) {
	      var isTypeEqual = true;
	
	      (0, _number.rangeEach)(Math.min(columnFrom, columnTo), Math.max(columnFrom, columnTo), function (column) {
	        var cellType = _this.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 `col` coordinates.
	   *
	   * @memberof Core#
	   * @function removeCellMeta
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @param {String} key Property name.
	   * @fires Hooks#beforeRemoveCellMeta
	   * @fires Hooks#afterRemoveCellMeta
	   */
	  this.removeCellMeta = function (row, col, key) {
	    var _recordTranslator$toP = recordTranslator.toPhysical(row, col),
	        _recordTranslator$toP2 = _slicedToArray(_recordTranslator$toP, 2),
	        physicalRow = _recordTranslator$toP2[0],
	        physicalColumn = _recordTranslator$toP2[1];
	
	    var cachedValue = priv.cellSettings[physicalRow][physicalColumn][key];
	
	    var hookResult = instance.runHooks('beforeRemoveCellMeta', row, col, key, cachedValue);
	
	    if (hookResult !== false) {
	      delete priv.cellSettings[physicalRow][physicalColumn][key];
	
	      instance.runHooks('afterRemoveCellMeta', row, col, 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 _len2 = arguments.length, items = Array(_len2 > 2 ? _len2 - 2 : 0), _key = 2; _key < _len2; _key++) {
	      items[_key - 2] = arguments[_key];
	    }
	
	    (_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 `col`.
	   *
	   * @memberof Core#
	   * @function setCellMetaObject
	   * @since 0.11
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @param {Object} prop Meta object.
	   */
	  this.setCellMetaObject = function (row, col, prop) {
	    if ((typeof prop === 'undefined' ? 'undefined' : _typeof(prop)) === 'object') {
	      for (var key in prop) {
	        if ((0, _object.hasOwnProperty)(prop, key)) {
	          var value = prop[key];
	          this.setCellMeta(row, col, key, value);
	        }
	      }
	    }
	  };
	
	  /**
	   * Sets a property defined by the `key` object to the meta object of a cell corresponding to params `row` and `col`.
	   *
	   * @memberof Core#
	   * @function setCellMeta
	   * @since 0.11
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @param {String} key Property name.
	   * @param {String} val Property value.
	   * @fires Hooks#afterSetCellMeta
	   */
	  this.setCellMeta = function (row, col, key, val) {
	    var _recordTranslator$toP3 = recordTranslator.toPhysical(row, col),
	        _recordTranslator$toP4 = _slicedToArray(_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] = val;
	    instance.runHooks('afterSetCellMeta', row, col, key, val);
	  };
	
	  /**
	   * Get all the cells meta settings at least once generated in the table (in order of cell initialization).
	   *
	   * @since 0.19.0
	   * @returns {Array} Returns Array of ColumnSettings object.
	   */
	  this.getCellsMeta = function () {
	    return (0, _array.arrayFlatten)(priv.cellSettings);
	  };
	
	  /**
	   * Returns the cell properties object for the given `row` and `col` coordinates.
	   *
	   * @memberof Core#
	   * @function getCellMeta
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @returns {Object} The cell properties object.
	   * @fires Hooks#beforeGetCellMeta
	   * @fires Hooks#afterGetCellMeta
	   */
	  this.getCellMeta = function (row, col) {
	    var prop = datamap.colToProp(col);
	    var cellProperties = void 0;
	
	    var _recordTranslator$toP5 = recordTranslator.toPhysical(row, col),
	        _recordTranslator$toP6 = _slicedToArray(_recordTranslator$toP5, 2),
	        physicalRow = _recordTranslator$toP6[0],
	        physicalColumn = _recordTranslator$toP6[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]();
	    }
	
	    cellProperties = priv.cellSettings[physicalRow][physicalColumn]; // retrieve cellProperties from cache
	
	    cellProperties.row = physicalRow;
	    cellProperties.col = physicalColumn;
	    cellProperties.visualRow = row;
	    cellProperties.visualCol = col;
	    cellProperties.prop = prop;
	    cellProperties.instance = instance;
	
	    instance.runHooks('beforeGetCellMeta', row, col, 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, col, cellProperties);
	
	    return cellProperties;
	  };
	
	  /**
	   * Returns a row off the cell meta array.
	   *
	   * @memberof Core#
	   * @function getCellMetaAtRow
	   * @since 0.30.0
	   * @param {Number} row Physical index of the row to return cell meta for.
	   * @returns {Array}
	   */
	  this.getCellMetaAtRow = function (row) {
	    return priv.cellSettings[row];
	  };
	
	  /**
	   * Checks if the data format and config allows user to modify the column structure.
	   * @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 `col` arguments.
	   *
	   * @memberof Core#
	   * @function getCellRenderer
	   * @since 0.11
	   * @param {Number|Object} row Visual row index or cell meta object.
	   * @param {Number} [col] Visual column index.
	   * @returns {Function} The renderer function.
	   */
	  this.getCellRenderer = function (row, col) {
	    return (0, _renderers.getRenderer)(rendererLookup.call(this, row, col));
	  };
	
	  /**
	   * Returns the cell editor by the provided `row` and `col` arguments.
	   *
	   * @memberof Core#
	   * @function getCellEditor
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @returns {Object} The Editor object.
	   */
	  this.getCellEditor = (0, _data.cellMethodLookupFactory)('editor');
	
	  var validatorLookup = (0, _data.cellMethodLookupFactory)('validator');
	
	  /**
	   * Returns the cell validator by `row` and `col`, provided a validator is defined. If not - it doesn't return anything.
	   *
	   * @memberof Core#
	   * @function getCellValidator
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @returns {Function|RegExp|undefined} The validator function.
	   */
	  this.getCellValidator = function (row, col) {
	    var validator = validatorLookup.call(this, row, col);
	
	    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.
	   */
	  this.validateCells = function (callback) {
	    var waitingForValidator = new ValidatorsQueue();
	
	    if (callback) {
	      waitingForValidator.onQueueEmpty = callback;
	    }
	
	    var i = instance.countRows() - 1;
	
	    while (i >= 0) {
	      var j = instance.countCols() - 1;
	
	      while (j >= 0) {
	        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--;
	      }
	      i--;
	    }
	    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} Array of header values / single header value.
	   */
	  this.getRowHeader = function (row) {
	    var rowHeader = priv.settings.rowHeaders;
	
	    if (row !== void 0) {
	      row = instance.runHooks('modifyRowHeader', row);
	    }
	    if (row === void 0) {
	      rowHeader = [];
	      (0, _number.rangeEach)(instance.countRows() - 1, function (i) {
	        rowHeader.push(instance.getRowHeader(i));
	      });
	    } else if (Array.isArray(rowHeader) && rowHeader[row] !== void 0) {
	      rowHeader = rowHeader[row];
	    } else if ((0, _function.isFunction)(rowHeader)) {
	      rowHeader = rowHeader(row);
	    } else if (rowHeader && typeof rowHeader !== 'string' && typeof rowHeader !== 'number') {
	      rowHeader = row + 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.
	   * @since 0.11
	   */
	  this.hasRowHeaders = function () {
	    return !!priv.settings.rowHeaders;
	  };
	
	  /**
	   * Returns information about if this table is configured to display column headers.
	   *
	   * @memberof Core#
	   * @function hasColHeaders
	   * @since 0.11
	   * @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 `col` is given, it returns the header at the given column as a string.
	   *
	   * @memberof Core#
	   * @function getColHeader
	   * @param {Number} [col] Visual column index.
	   * @fires Hooks#modifyColHeader
	   * @returns {Array|String} The column header(s).
	   */
	  this.getColHeader = function (col) {
	    var columnsAsFunc = priv.settings.columns && (0, _function.isFunction)(priv.settings.columns);
	    var result = priv.settings.colHeaders;
	
	    col = instance.runHooks('modifyColHeader', col);
	
	    if (col === 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(col) {
	        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[col];
	      };
	      var baseCol = col;
	      col = instance.runHooks('modifyCol', col);
	
	      var prop = translateVisualIndexToColumns(col);
	
	      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[col] && priv.settings.columns[col].title) {
	        result = priv.settings.columns[col].title;
	      } else if (Array.isArray(priv.settings.colHeaders) && priv.settings.colHeaders[col] !== void 0) {
	        result = priv.settings.colHeaders[col];
	      } else if ((0, _function.isFunction)(priv.settings.colHeaders)) {
	        result = priv.settings.colHeaders(col);
	      } 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 (typeof width === 'undefined' ? 'undefined' : _typeof(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
	   * @since 0.11
	   * @param {Number} col Visual column index.
	   * @returns {Number} Column width.
	   * @fires Hooks#modifyColWidth
	   */
	  this.getColWidth = function (col) {
	    var width = instance._getColWidthFromSettings(col);
	
	    width = instance.runHooks('modifyColWidth', width, col);
	
	    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 (typeof height === 'undefined' ? 'undefined' : _typeof(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
	   * @since 0.11
	   * @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
	   * @since 0.20.0
	   * @returns {Number} Total number in rows in data source.
	   */
	  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
	   * @since 0.26.1
	   * @returns {Number} Total number in columns in data source.
	   */
	  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 rows in the grid.
	   *
	   * @memberof Core#
	   * @function countRows
	   * @returns {Number} Total number in rows the grid.
	   */
	  this.countRows = function () {
	    return datamap.getLength();
	  };
	
	  /**
	   * Returns the total number of columns in the grid.
	   *
	   * @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++;
	            }
	          }
	
	          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] If `true`, will only count empty rows at the end of the data source.
	   * @returns {Number} Count empty rows
	   * @fires Hooks#modifyRow
	   */
	  this.countEmptyRows = function (ending) {
	    var i = instance.countRows() - 1,
	        empty = 0,
	        row;
	
	    while (i >= 0) {
	      row = instance.runHooks('modifyRow', i);
	
	      if (instance.isEmptyRow(row)) {
	        empty++;
	      } else if (ending) {
	        break;
	      }
	      i--;
	    }
	
	    return empty;
	  };
	
	  /**
	   * 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] If `true`, will only count empty columns at the end of the data source row.
	   * @returns {Number} Count empty cols
	   */
	  this.countEmptyCols = function (ending) {
	    if (instance.countRows() < 1) {
	      return 0;
	    }
	    var i = instance.countCols() - 1,
	        empty = 0;
	
	    while (i >= 0) {
	      if (instance.isEmptyCol(i)) {
	        empty++;
	      } else if (ending) {
	        break;
	      }
	      i--;
	    }
	
	    return empty;
	  };
	
	  /**
	   * Check if all cells in the row declared by the `row` argument are empty.
	   *
	   * @memberof Core#
	   * @function isEmptyRow
	   * @param {Number} row 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 `col` argument are empty.
	   *
	   * @memberof Core#
	   * @function isEmptyCol
	   * @param {Number} col Column index.
	   * @returns {Boolean} `true` if the column at the given `col` is empty, `false` otherwise.
	   */
	  this.isEmptyCol = function (col) {
	    return priv.settings.isEmptyCol.call(instance, col);
	  };
	
	  /**
	   * Select cell specified by `row` and `col` values or a range of cells finishing at `endRow`, `endCol`.
	   * By default, viewport will be scrolled to selection.
	   * After the `selectCell` method had finished, the instance will be listening to keyboard input on the document.
	   *
	   * @memberof Core#
	   * @function selectCell
	   * @param {Number} row Visual row index.
	   * @param {Number} col Visual column index.
	   * @param {Number} [endRow] Visual end row index (if selecting a range).
	   * @param {Number} [endCol] Visual end column index (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, col, endRow, endCol, scrollToCell, changeListener) {
	    var coords;
	
	    changeListener = (0, _mixed.isUndefined)(changeListener) || changeListener === true;
	
	    if (typeof row !== 'number' || row < 0 || row >= instance.countRows()) {
	      return false;
	    }
	    if (typeof col !== 'number' || col < 0 || col >= instance.countCols()) {
	      return false;
	    }
	    if ((0, _mixed.isDefined)(endRow)) {
	      if (typeof endRow !== 'number' || endRow < 0 || endRow >= instance.countRows()) {
	        return false;
	      }
	      if (typeof endCol !== 'number' || endCol < 0 || endCol >= instance.countCols()) {
	        return false;
	      }
	    }
	    coords = new _src.CellCoords(row, col);
	    priv.selRange = new _src.CellRange(coords, coords, coords);
	
	    if (changeListener) {
	      instance.listen();
	    }
	
	    if ((0, _mixed.isUndefined)(endRow)) {
	      selection.setRangeEnd(priv.selRange.from, scrollToCell);
	    } else {
	      selection.setRangeEnd(new _src.CellCoords(endRow, endCol), scrollToCell);
	    }
	    instance.selection.finish();
	    return true;
	  };
	
	  /**
	   * Select the cell specified by the `row` and `prop` arguments, or a range finishing at `endRow`, `endProp`.
	   * By default, viewport will be scrolled to selection.
	   *
	   * @memberof Core#
	   * @function selectCellByProp
	   * @param {Number} row Visual row index.
	   * @param {String} prop Property name.
	   * @param {Number} [endRow] visual end row index (if selecting a range).
	   * @param {String} [endProp] End property name (if selecting a range).
	   * @param {Boolean} [scrollToCell=true] If `true`, viewport will be scrolled to the selection.
	   * @returns {Boolean} `true` if selection was successful, `false` otherwise.
	   */
	  this.selectCellByProp = function (row, prop, endRow, endProp, scrollToCell) {
	    var _instance5;
	
	    arguments[1] = datamap.propToCol(arguments[1]);
	
	    if ((0, _mixed.isDefined)(arguments[3])) {
	      arguments[3] = datamap.propToCol(arguments[3]);
	    }
	
	    return (_instance5 = instance).selectCell.apply(_instance5, arguments);
	  };
	
	  /**
	   * Deselects the current cell selection on grid.
	   *
	   * @memberof Core#
	   * @function deselectCell
	   */
	  this.deselectCell = function () {
	    selection.deselect();
	  };
	
	  /**
	   * Scroll viewport to coords specified by the `row` and `column` arguments.
	   *
	   * @since 0.24.3
	   * @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;
	
	    if (row !== void 0 && (row < 0 || row >= instance.countRows())) {
	      return false;
	    }
	    if (column !== void 0 && (column < 0 || column >= instance.countCols())) {
	      return false;
	    }
	
	    var result = false;
	
	    if (row !== void 0 && column !== void 0) {
	      instance.view.wt.wtOverlays.topOverlay.scrollTo(row, snapToBottom);
	      instance.view.wt.wtOverlays.leftOverlay.scrollTo(column, snapToRight);
	
	      result = true;
	    }
	    if (typeof row === 'number' && typeof column !== 'number') {
	      instance.view.wt.wtOverlays.topOverlay.scrollTo(row, snapToBottom);
	
	      result = true;
	    }
	    if (typeof column === 'number' && typeof row !== 'number') {
	      instance.view.wt.wtOverlays.leftOverlay.scrollTo(column, snapToRight);
	
	      result = true;
	    }
	
	    return result;
	  };
	
	  /**
	   * Removes grid from the DOM.
	   *
	   * @memberof Core#
	   * @function destroy
	   * @fires Hooks#afterDestroy
	   */
	  this.destroy = function () {
	
	    instance._clearTimeouts();
	    if (instance.view) {
	      // in case HT is destroyed before initialization has finished
	      instance.view.destroy();
	    }
	    if (dataSource) {
	      dataSource.destroy();
	    }
	    dataSource = null;
	
	    if (false) {
	      var licenseInfo = document.querySelector('#hot-display-license-info');
	
	      if (licenseInfo) {
	        licenseInfo.parentNode.removeChild(licenseInfo);
	      }
	    }
	    (0, _element.empty)(instance.rootElement);
	    eventManager.destroy();
	
	    instance.runHooks('afterDestroy');
	    _pluginHooks2.default.getSingleton().destroy(instance);
	
	    for (var i in instance) {
	      if ((0, _object.hasOwnProperty)(instance, i)) {
	        // replace instance methods with post mortem
	        if ((0, _function.isFunction)(instance[i])) {
	          instance[i] = postMortem;
	        } else if (i !== '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
	          instance[i] = null;
	        }
	      }
	    }
	
	    // 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() {
	    throw new Error('This method cannot be called because this Handsontable instance has been destroyed');
	  }
	
	  /**
	   * Returns the active editor object.
	   *
	   * @memberof Core#
	   * @function getActiveEditor
	   * @returns {Object} The active editor object.
	   */
	  this.getActiveEditor = function () {
	    return editorManager.getActiveEditor();
	  };
	
	  /**
	   * Returns plugin instance using the plugin name provided.
	   *
	   * @memberof Core#
	   * @function getPlugin
	   * @param {String} pluginName The plugin name.
	   * @returns {*} The plugin instance.
	   * @since 0.15.0
	   */
	  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.
	   * @param {Function|Array} callback Function or array of Functions.
	   *
	   * @example
	   * ```js
	   * hot.addHook('beforeInit', myCallback);
	   * ```
	   */
	  this.addHook = function (key, callback) {
	    _pluginHooks2.default.getSingleton().add(key, callback, instance);
	  };
	
	  /**
	   * Check if for a specified hook name there are added listeners (only for this Handsontable instance).
	   *
	   * @memberof Core#
	   * @function hasHook
	   * @see Hooks#has
	   * @param {String} key Hook name
	   * @return {Boolean}
	   *
	   * @example
	   * ```js
	   * var hasBeforeInitListeners = hot.hasHook('beforeInit');
	   * ```
	   */
	  this.hasHook = function (key) {
	    return _pluginHooks2.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.
	   * @param {Function|Array} callback Function or array of Functions.
	   *
	   * @example
	   * ```js
	   * hot.addHookOnce('beforeInit', myCallback);
	   * ```
	   */
	  this.addHookOnce = function (key, callback) {
	    _pluginHooks2.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 Function which have been registered via {@link Core#addHook}.
	   *
	   * @example
	   * ```js
	   * hot.removeHook('beforeInit', myCallback);
	   * ```
	   */
	  this.removeHook = function (key, callback) {
	    _pluginHooks2.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
	   * hot.runHooks('beforeInit');
	   * ```
	   */
	  this.runHooks = function (key, p1, p2, p3, p4, p5, p6) {
	    return _pluginHooks2.default.getSingleton().run(instance, key, p1, p2, p3, p4, p5, p6);
	  };
	
	  this.timeouts = [];
	
	  /**
	   * Sets timeout. Purpose of this method is to clear all known timeouts when `destroy` method is called.
	   *
	   * @param {*} handle
	   * @private
	   */
	  this._registerTimeout = function (handle) {
	    this.timeouts.push(handle);
	  };
	
	  /**
	   * Clears all known timeouts.
	   *
	   * @private
	   */
	  this._clearTimeouts = function () {
	    for (var i = 0, ilen = this.timeouts.length; i < ilen; i++) {
	      clearTimeout(this.timeouts[i]);
	    }
	  };
	
	  /**
	   * Handsontable version
	   *
	   * @type {String}
	   */
	  // this.version = Handsontable.version;
	
	  _pluginHooks2.default.getSingleton().run(instance, 'construct');
	};
	
	/***/ }),
	/* 83 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.columnFactory = columnFactory;
	
	var _object = __webpack_require__(1);
	
	/* 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;
	}
	
	/***/ }),
	/* 84 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	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__(81);
	
	var _object = __webpack_require__(1);
	
	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 = void 0;
	
	  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;
	
	  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 = [],
	      i,
	      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 = [],
	      i,
	      j;
	
	  for (i = 0; i < rows; i++) {
	    var row = {};
	
	    for (j = 0; j < colCount; j++) {
	      row['prop' + 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 = void 0;
	
	  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 i,
	      ilen,
	      j,
	      jlen,
	      output = [],
	      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++;
	      }
	      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) {
	
	  allowUndefined = 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
	        var type;
	
	        if (typeof properties.type != 'string') {
	          throw new Error('Cell type must be a string ');
	        }
	        type = (0, _cellTypes.getCellType)(properties.type);
	
	        if ((0, _object.hasOwnProperty)(type, methodName)) {
	          return type[methodName]; // method defined in type.
	        } else if (allowUndefined) {
	          return; // method does not defined in type (eg. validator), returns undefined
	        }
	      }
	
	      return getMethodFromProperties(Object.getPrototypeOf(properties));
	    }(typeof row == 'number' ? this.getCellMeta(row, col) : row);
	  };
	}
	
	/***/ }),
	/* 85 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _array = __webpack_require__(2);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class GhostTable
	 * @util
	 */
	var GhostTable = function () {
	  function GhostTable(hotInstance) {
	    _classCallCheck(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.
	   */
	
	
	  _createClass(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) {
	      if (this.hot.getColHeader(0) != null) {
	        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 d = document;
	      var fragment = d.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 d = document;
	      var fragment = d.createDocumentFragment();
	      var th = d.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 = d.createElement('td');
	
	          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 d = document;
	      var fragment = d.createDocumentFragment();
	
	      if (this.hot.hasRowHeaders()) {
	        var th = d.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 = d.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 d = document;
	      var fragment = d.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 = d.createElement('td');
	          var tr = d.createElement('tr');
	
	          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 d = document;
	      var col = d.createElement('col');
	
	      col.style.width = 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 d = document;
	      var fragment = d.createDocumentFragment();
	      var table = d.createElement('table');
	      var tHead = d.createElement('thead');
	      var tBody = d.createElement('tbody');
	      var colGroup = d.createElement('colgroup');
	      var tr = d.createElement('tr');
	      var th = d.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 d = document;
	      var fragment = d.createDocumentFragment();
	      var container = d.createElement('div');
	
	      className = 'htGhostTable htAutoSize ' + className.trim();
	      (0, _element.addClass)(container, className);
	      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;
	}();
	
	exports.default = GhostTable;
	
	/***/ }),
	/* 86 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = separatorItem;
	var KEY = exports.KEY = '---------';
	
	function separatorItem() {
	  return {
	    name: KEY
	  };
	}
	
	/***/ }),
	/* 87 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _array = __webpack_require__(2);
	
	var _object = __webpack_require__(1);
	
	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
	   */
	  addLocalHook: function addLocalHook(key, callback) {
	    if (!this._localHooks[key]) {
	      this._localHooks[key] = [];
	    }
	    this._localHooks[key].push(callback);
	  },
	
	
	  /**
	   * Run hooks.
	   *
	   * @param {String} key Hook name.
	   * @param {*} params
	   */
	  runLocalHooks: function runLocalHooks(key) {
	    var _this = this;
	
	    for (var _len = arguments.length, params = 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.
	   */
	  clearLocalHooks: function clearLocalHooks() {
	    this._localHooks = {};
	  }
	};
	
	(0, _object.defineGetter)(localHooks, 'MIXIN_NAME', MIXIN_NAME, {
	  writable: false,
	  enumerable: false
	});
	
	exports.default = localHooks;
	
	/***/ }),
	/* 88 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.ITEMS = exports.UNDO = 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 = undefined;
	
	var _predefinedItems2;
	
	var _alignment = __webpack_require__(262);
	
	Object.defineProperty(exports, 'ALIGNMENT', {
	  enumerable: true,
	  get: function get() {
	    return _alignment.KEY;
	  }
	});
	
	var _clearColumn = __webpack_require__(263);
	
	Object.defineProperty(exports, 'CLEAR_COLUMN', {
	  enumerable: true,
	  get: function get() {
	    return _clearColumn.KEY;
	  }
	});
	
	var _columnLeft = __webpack_require__(264);
	
	Object.defineProperty(exports, 'COLUMN_LEFT', {
	  enumerable: true,
	  get: function get() {
	    return _columnLeft.KEY;
	  }
	});
	
	var _columnRight = __webpack_require__(265);
	
	Object.defineProperty(exports, 'COLUMN_RIGHT', {
	  enumerable: true,
	  get: function get() {
	    return _columnRight.KEY;
	  }
	});
	
	var _readOnly = __webpack_require__(266);
	
	Object.defineProperty(exports, 'READ_ONLY', {
	  enumerable: true,
	  get: function get() {
	    return _readOnly.KEY;
	  }
	});
	
	var _redo = __webpack_require__(267);
	
	Object.defineProperty(exports, 'REDO', {
	  enumerable: true,
	  get: function get() {
	    return _redo.KEY;
	  }
	});
	
	var _removeColumn = __webpack_require__(268);
	
	Object.defineProperty(exports, 'REMOVE_COLUMN', {
	  enumerable: true,
	  get: function get() {
	    return _removeColumn.KEY;
	  }
	});
	
	var _removeRow = __webpack_require__(269);
	
	Object.defineProperty(exports, 'REMOVE_ROW', {
	  enumerable: true,
	  get: function get() {
	    return _removeRow.KEY;
	  }
	});
	
	var _rowAbove = __webpack_require__(270);
	
	Object.defineProperty(exports, 'ROW_ABOVE', {
	  enumerable: true,
	  get: function get() {
	    return _rowAbove.KEY;
	  }
	});
	
	var _rowBelow = __webpack_require__(271);
	
	Object.defineProperty(exports, 'ROW_BELOW', {
	  enumerable: true,
	  get: function get() {
	    return _rowBelow.KEY;
	  }
	});
	
	var _separator = __webpack_require__(86);
	
	Object.defineProperty(exports, 'SEPARATOR', {
	  enumerable: true,
	  get: function get() {
	    return _separator.KEY;
	  }
	});
	
	var _undo = __webpack_require__(272);
	
	Object.defineProperty(exports, 'UNDO', {
	  enumerable: true,
	  get: function get() {
	    return _undo.KEY;
	  }
	});
	exports.predefinedItems = predefinedItems;
	exports.addItem = addItem;
	
	var _object = __webpack_require__(1);
	
	var _alignment2 = _interopRequireDefault(_alignment);
	
	var _clearColumn2 = _interopRequireDefault(_clearColumn);
	
	var _columnLeft2 = _interopRequireDefault(_columnLeft);
	
	var _columnRight2 = _interopRequireDefault(_columnRight);
	
	var _readOnly2 = _interopRequireDefault(_readOnly);
	
	var _redo2 = _interopRequireDefault(_redo);
	
	var _removeColumn2 = _interopRequireDefault(_removeColumn);
	
	var _removeRow2 = _interopRequireDefault(_removeRow);
	
	var _rowAbove2 = _interopRequireDefault(_rowAbove);
	
	var _rowBelow2 = _interopRequireDefault(_rowBelow);
	
	var _separator2 = _interopRequireDefault(_separator);
	
	var _undo2 = _interopRequireDefault(_undo);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	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; }
	
	var ITEMS = exports.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];
	
	var _predefinedItems = (_predefinedItems2 = {}, _defineProperty(_predefinedItems2, _separator.KEY, _separator2.default), _defineProperty(_predefinedItems2, _rowAbove.KEY, _rowAbove2.default), _defineProperty(_predefinedItems2, _rowBelow.KEY, _rowBelow2.default), _defineProperty(_predefinedItems2, _columnLeft.KEY, _columnLeft2.default), _defineProperty(_predefinedItems2, _columnRight.KEY, _columnRight2.default), _defineProperty(_predefinedItems2, _clearColumn.KEY, _clearColumn2.default), _defineProperty(_predefinedItems2, _removeRow.KEY, _removeRow2.default), _defineProperty(_predefinedItems2, _removeColumn.KEY, _removeColumn2.default), _defineProperty(_predefinedItems2, _undo.KEY, _undo2.default), _defineProperty(_predefinedItems2, _redo.KEY, _redo2.default), _defineProperty(_predefinedItems2, _readOnly.KEY, _readOnly2.default), _defineProperty(_predefinedItems2, _alignment.KEY, _alignment2.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;
	  }
	}
	
	/***/ }),
	/* 89 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var strong = __webpack_require__(90);
	var validate = __webpack_require__(39);
	var MAP = 'Map';
	
	// 23.1 Map Objects
	module.exports = __webpack_require__(59)(MAP, function (get) {
	  return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
	}, {
	  // 23.1.3.6 Map.prototype.get(key)
	  get: function get(key) {
	    var entry = strong.getEntry(validate(this, MAP), key);
	    return entry && entry.v;
	  },
	  // 23.1.3.9 Map.prototype.set(key, value)
	  set: function set(key, value) {
	    return strong.def(validate(this, MAP), key === 0 ? 0 : key, value);
	  }
	}, strong, true);
	
	
	/***/ }),
	/* 90 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var dP = __webpack_require__(17).f;
	var create = __webpack_require__(66);
	var redefineAll = __webpack_require__(54);
	var ctx = __webpack_require__(30);
	var anInstance = __webpack_require__(56);
	var forOf = __webpack_require__(57);
	var $iterDefine = __webpack_require__(99);
	var step = __webpack_require__(100);
	var setSpecies = __webpack_require__(101);
	var DESCRIPTORS = __webpack_require__(20);
	var fastKey = __webpack_require__(47).fastKey;
	var validate = __webpack_require__(39);
	var SIZE = DESCRIPTORS ? '_s' : 'size';
	
	var getEntry = function (that, key) {
	  // fast case
	  var index = fastKey(key);
	  var entry;
	  if (index !== 'F') return that._i[index];
	  // frozen object case
	  for (entry = that._f; entry; entry = entry.n) {
	    if (entry.k == key) return entry;
	  }
	};
	
	module.exports = {
	  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
	    var C = wrapper(function (that, iterable) {
	      anInstance(that, C, NAME, '_i');
	      that._t = NAME;         // collection type
	      that._i = create(null); // index
	      that._f = undefined;    // first entry
	      that._l = undefined;    // last entry
	      that[SIZE] = 0;         // size
	      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
	    });
	    redefineAll(C.prototype, {
	      // 23.1.3.1 Map.prototype.clear()
	      // 23.2.3.2 Set.prototype.clear()
	      clear: function clear() {
	        for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {
	          entry.r = true;
	          if (entry.p) entry.p = entry.p.n = undefined;
	          delete data[entry.i];
	        }
	        that._f = that._l = undefined;
	        that[SIZE] = 0;
	      },
	      // 23.1.3.3 Map.prototype.delete(key)
	      // 23.2.3.4 Set.prototype.delete(value)
	      'delete': function (key) {
	        var that = validate(this, NAME);
	        var entry = getEntry(that, key);
	        if (entry) {
	          var next = entry.n;
	          var prev = entry.p;
	          delete that._i[entry.i];
	          entry.r = true;
	          if (prev) prev.n = next;
	          if (next) next.p = prev;
	          if (that._f == entry) that._f = next;
	          if (that._l == entry) that._l = prev;
	          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 */) {
	        validate(this, NAME);
	        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
	        var entry;
	        while (entry = entry ? entry.n : this._f) {
	          f(entry.v, entry.k, this);
	          // revert to the last existing entry
	          while (entry && entry.r) entry = entry.p;
	        }
	      },
	      // 23.1.3.7 Map.prototype.has(key)
	      // 23.2.3.7 Set.prototype.has(value)
	      has: function has(key) {
	        return !!getEntry(validate(this, NAME), key);
	      }
	    });
	    if (DESCRIPTORS) dP(C.prototype, 'size', {
	      get: function () {
	        return validate(this, NAME)[SIZE];
	      }
	    });
	    return C;
	  },
	  def: function (that, key, value) {
	    var entry = getEntry(that, key);
	    var prev, index;
	    // change existing entry
	    if (entry) {
	      entry.v = value;
	    // create new entry
	    } else {
	      that._l = entry = {
	        i: index = fastKey(key, true), // <- index
	        k: key,                        // <- key
	        v: value,                      // <- value
	        p: prev = that._l,             // <- previous entry
	        n: undefined,                  // <- next entry
	        r: false                       // <- removed
	      };
	      if (!that._f) that._f = entry;
	      if (prev) prev.n = entry;
	      that[SIZE]++;
	      // add to index
	      if (index !== 'F') that._i[index] = entry;
	    } return that;
	  },
	  getEntry: getEntry,
	  setStrong: function (C, NAME, IS_MAP) {
	    // 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
	    $iterDefine(C, NAME, function (iterated, kind) {
	      this._t = validate(iterated, NAME); // target
	      this._k = kind;                     // kind
	      this._l = undefined;                // previous
	    }, function () {
	      var that = this;
	      var kind = that._k;
	      var entry = that._l;
	      // revert to the last existing entry
	      while (entry && entry.r) entry = entry.p;
	      // get next entry
	      if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {
	        // or finish the iteration
	        that._t = undefined;
	        return step(1);
	      }
	      // return step by kind
	      if (kind == 'keys') return step(0, entry.k);
	      if (kind == 'values') return step(0, entry.v);
	      return step(0, [entry.k, entry.v]);
	    }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);
	
	    // add [@@species], 23.1.2.2, 23.2.2.2
	    setSpecies(NAME);
	  }
	};
	
	
	/***/ }),
	/* 91 */
	/***/ (function(module, exports, __webpack_require__) {
	
	module.exports = !__webpack_require__(20) && !__webpack_require__(23)(function () {
	  return Object.defineProperty(__webpack_require__(64)('div'), 'a', { get: function () { return 7; } }).a != 7;
	});
	
	
	/***/ }),
	/* 92 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var has = __webpack_require__(24);
	var toIObject = __webpack_require__(25);
	var arrayIndexOf = __webpack_require__(93)(false);
	var IE_PROTO = __webpack_require__(68)('IE_PROTO');
	
	module.exports = function (object, names) {
	  var O = toIObject(object);
	  var i = 0;
	  var result = [];
	  var key;
	  for (key in O) if (key != IE_PROTO) 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;
	};
	
	
	/***/ }),
	/* 93 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// false -> Array#indexOf
	// true  -> Array#includes
	var toIObject = __webpack_require__(25);
	var toLength = __webpack_require__(21);
	var toAbsoluteIndex = __webpack_require__(53);
	module.exports = function (IS_INCLUDES) {
	  return function ($this, el, fromIndex) {
	    var O = toIObject($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;
	  };
	};
	
	
	/***/ }),
	/* 94 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var document = __webpack_require__(11).document;
	module.exports = document && document.documentElement;
	
	
	/***/ }),
	/* 95 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// call something on iterator step with safe closing on error
	var anObject = __webpack_require__(16);
	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 ret = iterator['return'];
	    if (ret !== undefined) anObject(ret.call(iterator));
	    throw e;
	  }
	};
	
	
	/***/ }),
	/* 96 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// check on default Array iterator
	var Iterators = __webpack_require__(45);
	var ITERATOR = __webpack_require__(9)('iterator');
	var ArrayProto = Array.prototype;
	
	module.exports = function (it) {
	  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
	};
	
	
	/***/ }),
	/* 97 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var classof = __webpack_require__(98);
	var ITERATOR = __webpack_require__(9)('iterator');
	var Iterators = __webpack_require__(45);
	module.exports = __webpack_require__(44).getIteratorMethod = function (it) {
	  if (it != undefined) return it[ITERATOR]
	    || it['@@iterator']
	    || Iterators[classof(it)];
	};
	
	
	/***/ }),
	/* 98 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// getting tag from 19.1.3.6 Object.prototype.toString()
	var cof = __webpack_require__(37);
	var TAG = __webpack_require__(9)('toStringTag');
	// ES3 wrong here
	var ARG = cof(function () { return arguments; }()) == 'Arguments';
	
	// fallback for IE11 Script Access Denied error
	var tryGet = function (it, key) {
	  try {
	    return it[key];
	  } catch (e) { /* empty */ }
	};
	
	module.exports = function (it) {
	  var O, T, B;
	  return it === undefined ? 'Undefined' : it === null ? 'Null'
	    // @@toStringTag case
	    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
	    // builtinTag case
	    : ARG ? cof(O)
	    // ES3 arguments fallback
	    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
	};
	
	
	/***/ }),
	/* 99 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var LIBRARY = __webpack_require__(58);
	var $export = __webpack_require__(3);
	var redefine = __webpack_require__(28);
	var hide = __webpack_require__(29);
	var has = __webpack_require__(24);
	var Iterators = __webpack_require__(45);
	var $iterCreate = __webpack_require__(182);
	var setToStringTag = __webpack_require__(46);
	var getPrototypeOf = __webpack_require__(183);
	var ITERATOR = __webpack_require__(9)('iterator');
	var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
	var FF_ITERATOR = '@@iterator';
	var KEYS = 'keys';
	var VALUES = 'values';
	
	var returnThis = function () { return this; };
	
	module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
	  $iterCreate(Constructor, NAME, next);
	  var getMethod = function (kind) {
	    if (!BUGGY && kind in proto) return proto[kind];
	    switch (kind) {
	      case KEYS: return function keys() { return new Constructor(this, kind); };
	      case VALUES: return function values() { return new Constructor(this, kind); };
	    } return function entries() { return new Constructor(this, kind); };
	  };
	  var TAG = NAME + ' Iterator';
	  var DEF_VALUES = DEFAULT == VALUES;
	  var VALUES_BUG = false;
	  var proto = Base.prototype;
	  var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
	  var $default = $native || getMethod(DEFAULT);
	  var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
	  var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
	  var methods, key, IteratorPrototype;
	  // Fix native
	  if ($anyNative) {
	    IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));
	    if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
	      // Set @@toStringTag to native iterators
	      setToStringTag(IteratorPrototype, TAG, true);
	      // fix for some old engines
	      if (!LIBRARY && !has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis);
	    }
	  }
	  // fix Array#{values, @@iterator}.name in V8 / FF
	  if (DEF_VALUES && $native && $native.name !== VALUES) {
	    VALUES_BUG = true;
	    $default = function values() { return $native.call(this); };
	  }
	  // Define iterator
	  if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
	    hide(proto, ITERATOR, $default);
	  }
	  // Plug for library
	  Iterators[NAME] = $default;
	  Iterators[TAG] = returnThis;
	  if (DEFAULT) {
	    methods = {
	      values: DEF_VALUES ? $default : getMethod(VALUES),
	      keys: IS_SET ? $default : getMethod(KEYS),
	      entries: $entries
	    };
	    if (FORCED) for (key in methods) {
	      if (!(key in proto)) redefine(proto, key, methods[key]);
	    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
	  }
	  return methods;
	};
	
	
	/***/ }),
	/* 100 */
	/***/ (function(module, exports) {
	
	module.exports = function (done, value) {
	  return { value: value, done: !!done };
	};
	
	
	/***/ }),
	/* 101 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var global = __webpack_require__(11);
	var dP = __webpack_require__(17);
	var DESCRIPTORS = __webpack_require__(20);
	var SPECIES = __webpack_require__(9)('species');
	
	module.exports = function (KEY) {
	  var C = global[KEY];
	  if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {
	    configurable: true,
	    get: function () { return this; }
	  });
	};
	
	
	/***/ }),
	/* 102 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// Works with __proto__ only. Old v8 can't work with null proto objects.
	/* eslint-disable no-proto */
	var isObject = __webpack_require__(14);
	var anObject = __webpack_require__(16);
	var check = function (O, proto) {
	  anObject(O);
	  if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
	};
	module.exports = {
	  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
	    function (test, buggy, set) {
	      try {
	        set = __webpack_require__(30)(Function.call, __webpack_require__(72).f(Object.prototype, '__proto__').set, 2);
	        set(test, []);
	        buggy = !(test instanceof Array);
	      } catch (e) { buggy = true; }
	      return function setPrototypeOf(O, proto) {
	        check(O, proto);
	        if (buggy) O.__proto__ = proto;
	        else set(O, proto);
	        return O;
	      };
	    }({}, false) : undefined),
	  check: check
	};
	
	
	/***/ }),
	/* 103 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var strong = __webpack_require__(90);
	var validate = __webpack_require__(39);
	var SET = 'Set';
	
	// 23.2 Set Objects
	module.exports = __webpack_require__(59)(SET, function (get) {
	  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
	}, {
	  // 23.2.3.1 Set.prototype.add(value)
	  add: function add(value) {
	    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
	  }
	}, strong);
	
	
	/***/ }),
	/* 104 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var each = __webpack_require__(60)(0);
	var redefine = __webpack_require__(28);
	var meta = __webpack_require__(47);
	var assign = __webpack_require__(106);
	var weak = __webpack_require__(107);
	var isObject = __webpack_require__(14);
	var fails = __webpack_require__(23);
	var validate = __webpack_require__(39);
	var WEAK_MAP = 'WeakMap';
	var getWeak = meta.getWeak;
	var isExtensible = Object.isExtensible;
	var uncaughtFrozenStore = weak.ufstore;
	var tmp = {};
	var InternalMap;
	
	var wrapper = function (get) {
	  return function WeakMap() {
	    return get(this, arguments.length > 0 ? arguments[0] : undefined);
	  };
	};
	
	var methods = {
	  // 23.3.3.3 WeakMap.prototype.get(key)
	  get: function get(key) {
	    if (isObject(key)) {
	      var data = getWeak(key);
	      if (data === true) return uncaughtFrozenStore(validate(this, WEAK_MAP)).get(key);
	      return data ? data[this._i] : undefined;
	    }
	  },
	  // 23.3.3.5 WeakMap.prototype.set(key, value)
	  set: function set(key, value) {
	    return weak.def(validate(this, WEAK_MAP), key, value);
	  }
	};
	
	// 23.3 WeakMap Objects
	var $WeakMap = module.exports = __webpack_require__(59)(WEAK_MAP, wrapper, methods, weak, true, true);
	
	// IE11 WeakMap frozen keys fix
	if (fails(function () { return new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7; })) {
	  InternalMap = weak.getConstructor(wrapper, WEAK_MAP);
	  assign(InternalMap.prototype, methods);
	  meta.NEED = true;
	  each(['delete', 'has', 'get', 'set'], function (key) {
	    var proto = $WeakMap.prototype;
	    var method = proto[key];
	    redefine(proto, key, function (a, b) {
	      // store frozen objects on internal weakmap shim
	      if (isObject(a) && !isExtensible(a)) {
	        if (!this._f) this._f = new InternalMap();
	        var result = this._f[key](a, b);
	        return key == 'set' ? this : result;
	      // store all the rest on native weakmap
	      } return method.call(this, a, b);
	    });
	  });
	}
	
	
	/***/ }),
	/* 105 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 7.2.2 IsArray(argument)
	var cof = __webpack_require__(37);
	module.exports = Array.isArray || function isArray(arg) {
	  return cof(arg) == 'Array';
	};
	
	
	/***/ }),
	/* 106 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// 19.1.2.1 Object.assign(target, source, ...)
	var getKeys = __webpack_require__(36);
	var gOPS = __webpack_require__(61);
	var pIE = __webpack_require__(48);
	var toObject = __webpack_require__(38);
	var IObject = __webpack_require__(67);
	var $assign = Object.assign;
	
	// should work with symbols and should have deterministic property order (V8 bug)
	module.exports = !$assign || __webpack_require__(23)(function () {
	  var A = {};
	  var B = {};
	  // eslint-disable-next-line no-undef
	  var S = Symbol();
	  var K = 'abcdefghijklmnopqrst';
	  A[S] = 7;
	  K.split('').forEach(function (k) { B[k] = k; });
	  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
	}) ? function assign(target, source) { // eslint-disable-line no-unused-vars
	  var T = toObject(target);
	  var aLen = arguments.length;
	  var index = 1;
	  var getSymbols = gOPS.f;
	  var isEnum = pIE.f;
	  while (aLen > index) {
	    var S = IObject(arguments[index++]);
	    var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);
	    var length = keys.length;
	    var j = 0;
	    var key;
	    while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];
	  } return T;
	} : $assign;
	
	
	/***/ }),
	/* 107 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var redefineAll = __webpack_require__(54);
	var getWeak = __webpack_require__(47).getWeak;
	var anObject = __webpack_require__(16);
	var isObject = __webpack_require__(14);
	var anInstance = __webpack_require__(56);
	var forOf = __webpack_require__(57);
	var createArrayMethod = __webpack_require__(60);
	var $has = __webpack_require__(24);
	var validate = __webpack_require__(39);
	var arrayFind = createArrayMethod(5);
	var arrayFindIndex = createArrayMethod(6);
	var id = 0;
	
	// fallback for uncaught frozen keys
	var uncaughtFrozenStore = function (that) {
	  return that._l || (that._l = new UncaughtFrozenStore());
	};
	var UncaughtFrozenStore = function () {
	  this.a = [];
	};
	var findUncaughtFrozen = function (store, key) {
	  return arrayFind(store.a, 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.a.push([key, value]);
	  },
	  'delete': function (key) {
	    var index = arrayFindIndex(this.a, function (it) {
	      return it[0] === key;
	    });
	    if (~index) this.a.splice(index, 1);
	    return !!~index;
	  }
	};
	
	module.exports = {
	  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
	    var C = wrapper(function (that, iterable) {
	      anInstance(that, C, NAME, '_i');
	      that._t = NAME;      // collection type
	      that._i = id++;      // collection id
	      that._l = undefined; // leak store for uncaught frozen objects
	      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
	    });
	    redefineAll(C.prototype, {
	      // 23.3.3.2 WeakMap.prototype.delete(key)
	      // 23.4.3.3 WeakSet.prototype.delete(value)
	      'delete': function (key) {
	        if (!isObject(key)) return false;
	        var data = getWeak(key);
	        if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key);
	        return data && $has(data, this._i) && delete data[this._i];
	      },
	      // 23.3.3.4 WeakMap.prototype.has(key)
	      // 23.4.3.4 WeakSet.prototype.has(value)
	      has: function has(key) {
	        if (!isObject(key)) return false;
	        var data = getWeak(key);
	        if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key);
	        return data && $has(data, this._i);
	      }
	    });
	    return C;
	  },
	  def: function (that, key, value) {
	    var data = getWeak(anObject(key), true);
	    if (data === true) uncaughtFrozenStore(that).set(key, value);
	    else data[that._i] = value;
	    return that;
	  },
	  ufstore: uncaughtFrozenStore
	};
	
	
	/***/ }),
	/* 108 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var weak = __webpack_require__(107);
	var validate = __webpack_require__(39);
	var WEAK_SET = 'WeakSet';
	
	// 23.4 WeakSet Objects
	__webpack_require__(59)(WEAK_SET, function (get) {
	  return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
	}, {
	  // 23.4.3.1 WeakSet.prototype.add(value)
	  add: function add(value) {
	    return weak.def(validate(this, WEAK_SET), value, true);
	  }
	}, weak, false, true);
	
	
	/***/ }),
	/* 109 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var LIBRARY = __webpack_require__(58);
	var global = __webpack_require__(11);
	var ctx = __webpack_require__(30);
	var classof = __webpack_require__(98);
	var $export = __webpack_require__(3);
	var isObject = __webpack_require__(14);
	var aFunction = __webpack_require__(55);
	var anInstance = __webpack_require__(56);
	var forOf = __webpack_require__(57);
	var speciesConstructor = __webpack_require__(187);
	var task = __webpack_require__(73).set;
	var microtask = __webpack_require__(189)();
	var newPromiseCapabilityModule = __webpack_require__(110);
	var perform = __webpack_require__(190);
	var promiseResolve = __webpack_require__(191);
	var PROMISE = 'Promise';
	var TypeError = global.TypeError;
	var process = global.process;
	var $Promise = global[PROMISE];
	var isNode = classof(process) == 'process';
	var empty = function () { /* empty */ };
	var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;
	var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;
	
	var USE_NATIVE = !!function () {
	  try {
	    // correct subclassing with @@species support
	    var promise = $Promise.resolve(1);
	    var FakePromise = (promise.constructor = {})[__webpack_require__(9)('species')] = function (exec) {
	      exec(empty, empty);
	    };
	    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
	    return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
	  } catch (e) { /* empty */ }
	}();
	
	// helpers
	var isThenable = function (it) {
	  var then;
	  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
	};
	var notify = function (promise, isReject) {
	  if (promise._n) return;
	  promise._n = true;
	  var chain = promise._c;
	  microtask(function () {
	    var value = promise._v;
	    var ok = promise._s == 1;
	    var i = 0;
	    var run = function (reaction) {
	      var handler = ok ? reaction.ok : reaction.fail;
	      var resolve = reaction.resolve;
	      var reject = reaction.reject;
	      var domain = reaction.domain;
	      var result, then;
	      try {
	        if (handler) {
	          if (!ok) {
	            if (promise._h == 2) onHandleUnhandled(promise);
	            promise._h = 1;
	          }
	          if (handler === true) result = value;
	          else {
	            if (domain) domain.enter();
	            result = handler(value);
	            if (domain) domain.exit();
	          }
	          if (result === reaction.promise) {
	            reject(TypeError('Promise-chain cycle'));
	          } else if (then = isThenable(result)) {
	            then.call(result, resolve, reject);
	          } else resolve(result);
	        } else reject(value);
	      } catch (e) {
	        reject(e);
	      }
	    };
	    while (chain.length > i) run(chain[i++]); // variable length - can't use forEach
	    promise._c = [];
	    promise._n = false;
	    if (isReject && !promise._h) onUnhandled(promise);
	  });
	};
	var onUnhandled = function (promise) {
	  task.call(global, function () {
	    var value = promise._v;
	    var unhandled = isUnhandled(promise);
	    var result, handler, console;
	    if (unhandled) {
	      result = perform(function () {
	        if (isNode) {
	          process.emit('unhandledRejection', value, promise);
	        } else if (handler = global.onunhandledrejection) {
	          handler({ promise: promise, reason: value });
	        } else if ((console = global.console) && console.error) {
	          console.error('Unhandled promise rejection', value);
	        }
	      });
	      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
	      promise._h = isNode || isUnhandled(promise) ? 2 : 1;
	    } promise._a = undefined;
	    if (unhandled && result.e) throw result.v;
	  });
	};
	var isUnhandled = function (promise) {
	  if (promise._h == 1) return false;
	  var chain = promise._a || promise._c;
	  var i = 0;
	  var reaction;
	  while (chain.length > i) {
	    reaction = chain[i++];
	    if (reaction.fail || !isUnhandled(reaction.promise)) return false;
	  } return true;
	};
	var onHandleUnhandled = function (promise) {
	  task.call(global, function () {
	    var handler;
	    if (isNode) {
	      process.emit('rejectionHandled', promise);
	    } else if (handler = global.onrejectionhandled) {
	      handler({ promise: promise, reason: promise._v });
	    }
	  });
	};
	var $reject = function (value) {
	  var promise = this;
	  if (promise._d) return;
	  promise._d = true;
	  promise = promise._w || promise; // unwrap
	  promise._v = value;
	  promise._s = 2;
	  if (!promise._a) promise._a = promise._c.slice();
	  notify(promise, true);
	};
	var $resolve = function (value) {
	  var promise = this;
	  var then;
	  if (promise._d) return;
	  promise._d = true;
	  promise = promise._w || promise; // unwrap
	  try {
	    if (promise === value) throw TypeError("Promise can't be resolved itself");
	    if (then = isThenable(value)) {
	      microtask(function () {
	        var wrapper = { _w: promise, _d: false }; // wrap
	        try {
	          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
	        } catch (e) {
	          $reject.call(wrapper, e);
	        }
	      });
	    } else {
	      promise._v = value;
	      promise._s = 1;
	      notify(promise, false);
	    }
	  } catch (e) {
	    $reject.call({ _w: promise, _d: false }, e); // wrap
	  }
	};
	
	// constructor polyfill
	if (!USE_NATIVE) {
	  // 25.4.3.1 Promise(executor)
	  $Promise = function Promise(executor) {
	    anInstance(this, $Promise, PROMISE, '_h');
	    aFunction(executor);
	    Internal.call(this);
	    try {
	      executor(ctx($resolve, this, 1), ctx($reject, this, 1));
	    } catch (err) {
	      $reject.call(this, err);
	    }
	  };
	  // eslint-disable-next-line no-unused-vars
	  Internal = function Promise(executor) {
	    this._c = [];             // <- awaiting reactions
	    this._a = undefined;      // <- checked in isUnhandled reactions
	    this._s = 0;              // <- state
	    this._d = false;          // <- done
	    this._v = undefined;      // <- value
	    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
	    this._n = false;          // <- notify
	  };
	  Internal.prototype = __webpack_require__(54)($Promise.prototype, {
	    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
	    then: function then(onFulfilled, onRejected) {
	      var reaction = newPromiseCapability(speciesConstructor(this, $Promise));
	      reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
	      reaction.fail = typeof onRejected == 'function' && onRejected;
	      reaction.domain = isNode ? process.domain : undefined;
	      this._c.push(reaction);
	      if (this._a) this._a.push(reaction);
	      if (this._s) notify(this, false);
	      return reaction.promise;
	    },
	    // 25.4.5.1 Promise.prototype.catch(onRejected)
	    'catch': function (onRejected) {
	      return this.then(undefined, onRejected);
	    }
	  });
	  OwnPromiseCapability = function () {
	    var promise = new Internal();
	    this.promise = promise;
	    this.resolve = ctx($resolve, promise, 1);
	    this.reject = ctx($reject, promise, 1);
	  };
	  newPromiseCapabilityModule.f = newPromiseCapability = function (C) {
	    return C === $Promise || C === Wrapper
	      ? new OwnPromiseCapability(C)
	      : newGenericPromiseCapability(C);
	  };
	}
	
	$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });
	__webpack_require__(46)($Promise, PROMISE);
	__webpack_require__(101)(PROMISE);
	Wrapper = __webpack_require__(44)[PROMISE];
	
	// statics
	$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
	  // 25.4.4.5 Promise.reject(r)
	  reject: function reject(r) {
	    var capability = newPromiseCapability(this);
	    var $$reject = capability.reject;
	    $$reject(r);
	    return capability.promise;
	  }
	});
	$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
	  // 25.4.4.6 Promise.resolve(x)
	  resolve: function resolve(x) {
	    return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);
	  }
	});
	$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(71)(function (iter) {
	  $Promise.all(iter)['catch'](empty);
	})), PROMISE, {
	  // 25.4.4.1 Promise.all(iterable)
	  all: function all(iterable) {
	    var C = this;
	    var capability = newPromiseCapability(C);
	    var resolve = capability.resolve;
	    var reject = capability.reject;
	    var result = perform(function () {
	      var values = [];
	      var index = 0;
	      var remaining = 1;
	      forOf(iterable, false, function (promise) {
	        var $index = index++;
	        var alreadyCalled = false;
	        values.push(undefined);
	        remaining++;
	        C.resolve(promise).then(function (value) {
	          if (alreadyCalled) return;
	          alreadyCalled = true;
	          values[$index] = value;
	          --remaining || resolve(values);
	        }, reject);
	      });
	      --remaining || resolve(values);
	    });
	    if (result.e) reject(result.v);
	    return capability.promise;
	  },
	  // 25.4.4.4 Promise.race(iterable)
	  race: function race(iterable) {
	    var C = this;
	    var capability = newPromiseCapability(C);
	    var reject = capability.reject;
	    var result = perform(function () {
	      forOf(iterable, false, function (promise) {
	        C.resolve(promise).then(capability.resolve, reject);
	      });
	    });
	    if (result.e) reject(result.v);
	    return capability.promise;
	  }
	});
	
	
	/***/ }),
	/* 110 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// 25.4.1.5 NewPromiseCapability(C)
	var aFunction = __webpack_require__(55);
	
	function PromiseCapability(C) {
	  var resolve, reject;
	  this.promise = new C(function ($$resolve, $$reject) {
	    if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
	    resolve = $$resolve;
	    reject = $$reject;
	  });
	  this.resolve = aFunction(resolve);
	  this.reject = aFunction(reject);
	}
	
	module.exports.f = function (C) {
	  return new PromiseCapability(C);
	};
	
	
	/***/ }),
	/* 111 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// ECMAScript 6 symbols shim
	var global = __webpack_require__(11);
	var has = __webpack_require__(24);
	var DESCRIPTORS = __webpack_require__(20);
	var $export = __webpack_require__(3);
	var redefine = __webpack_require__(28);
	var META = __webpack_require__(47).KEY;
	var $fails = __webpack_require__(23);
	var shared = __webpack_require__(69);
	var setToStringTag = __webpack_require__(46);
	var uid = __webpack_require__(42);
	var wks = __webpack_require__(9);
	var wksExt = __webpack_require__(112);
	var wksDefine = __webpack_require__(192);
	var enumKeys = __webpack_require__(193);
	var isArray = __webpack_require__(105);
	var anObject = __webpack_require__(16);
	var toIObject = __webpack_require__(25);
	var toPrimitive = __webpack_require__(65);
	var createDesc = __webpack_require__(43);
	var _create = __webpack_require__(66);
	var gOPNExt = __webpack_require__(194);
	var $GOPD = __webpack_require__(72);
	var $DP = __webpack_require__(17);
	var $keys = __webpack_require__(36);
	var gOPD = $GOPD.f;
	var dP = $DP.f;
	var gOPN = gOPNExt.f;
	var $Symbol = global.Symbol;
	var $JSON = global.JSON;
	var _stringify = $JSON && $JSON.stringify;
	var PROTOTYPE = 'prototype';
	var HIDDEN = wks('_hidden');
	var TO_PRIMITIVE = wks('toPrimitive');
	var isEnum = {}.propertyIsEnumerable;
	var SymbolRegistry = shared('symbol-registry');
	var AllSymbols = shared('symbols');
	var OPSymbols = shared('op-symbols');
	var ObjectProto = Object[PROTOTYPE];
	var USE_NATIVE = typeof $Symbol == 'function';
	var QObject = global.QObject;
	// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
	var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;
	
	// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
	var setSymbolDesc = DESCRIPTORS && $fails(function () {
	  return _create(dP({}, 'a', {
	    get: function () { return dP(this, 'a', { value: 7 }).a; }
	  })).a != 7;
	}) ? function (it, key, D) {
	  var protoDesc = gOPD(ObjectProto, key);
	  if (protoDesc) delete ObjectProto[key];
	  dP(it, key, D);
	  if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc);
	} : dP;
	
	var wrap = function (tag) {
	  var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);
	  sym._k = tag;
	  return sym;
	};
	
	var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) {
	  return typeof it == 'symbol';
	} : function (it) {
	  return it instanceof $Symbol;
	};
	
	var $defineProperty = function defineProperty(it, key, D) {
	  if (it === ObjectProto) $defineProperty(OPSymbols, key, D);
	  anObject(it);
	  key = toPrimitive(key, true);
	  anObject(D);
	  if (has(AllSymbols, key)) {
	    if (!D.enumerable) {
	      if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {}));
	      it[HIDDEN][key] = true;
	    } else {
	      if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;
	      D = _create(D, { enumerable: createDesc(0, false) });
	    } return setSymbolDesc(it, key, D);
	  } return dP(it, key, D);
	};
	var $defineProperties = function defineProperties(it, P) {
	  anObject(it);
	  var keys = enumKeys(P = toIObject(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 ? _create(it) : $defineProperties(_create(it), P);
	};
	var $propertyIsEnumerable = function propertyIsEnumerable(key) {
	  var E = isEnum.call(this, key = toPrimitive(key, true));
	  if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, 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 = toIObject(it);
	  key = toPrimitive(key, true);
	  if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return;
	  var D = gOPD(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 = gOPN(toIObject(it));
	  var result = [];
	  var i = 0;
	  var key;
	  while (names.length > i) {
	    if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key);
	  } return result;
	};
	var $getOwnPropertySymbols = function getOwnPropertySymbols(it) {
	  var IS_OP = it === ObjectProto;
	  var names = gOPN(IS_OP ? OPSymbols : toIObject(it));
	  var result = [];
	  var i = 0;
	  var key;
	  while (names.length > i) {
	    if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]);
	  } return result;
	};
	
	// 19.4.1.1 Symbol([description])
	if (!USE_NATIVE) {
	  $Symbol = function Symbol() {
	    if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!');
	    var tag = uid(arguments.length > 0 ? arguments[0] : undefined);
	    var $set = function (value) {
	      if (this === ObjectProto) $set.call(OPSymbols, value);
	      if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
	      setSymbolDesc(this, tag, createDesc(1, value));
	    };
	    if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set });
	    return wrap(tag);
	  };
	  redefine($Symbol[PROTOTYPE], 'toString', function toString() {
	    return this._k;
	  });
	
	  $GOPD.f = $getOwnPropertyDescriptor;
	  $DP.f = $defineProperty;
	  __webpack_require__(74).f = gOPNExt.f = $getOwnPropertyNames;
	  __webpack_require__(48).f = $propertyIsEnumerable;
	  __webpack_require__(61).f = $getOwnPropertySymbols;
	
	  if (DESCRIPTORS && !__webpack_require__(58)) {
	    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
	  }
	
	  wksExt.f = function (name) {
	    return wrap(wks(name));
	  };
	}
	
	$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol });
	
	for (var es6Symbols = (
	  // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
	  'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
	).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]);
	
	for (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]);
	
	$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {
	  // 19.4.2.1 Symbol.for(key)
	  'for': function (key) {
	    return has(SymbolRegistry, key += '')
	      ? SymbolRegistry[key]
	      : SymbolRegistry[key] = $Symbol(key);
	  },
	  // 19.4.2.5 Symbol.keyFor(sym)
	  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 () { setter = true; },
	  useSimple: function () { setter = false; }
	});
	
	$export($export.S + $export.F * !USE_NATIVE, 'Object', {
	  // 19.1.2.2 Object.create(O [, Properties])
	  create: $create,
	  // 19.1.2.4 Object.defineProperty(O, P, Attributes)
	  defineProperty: $defineProperty,
	  // 19.1.2.3 Object.defineProperties(O, Properties)
	  defineProperties: $defineProperties,
	  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
	  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
	  // 19.1.2.7 Object.getOwnPropertyNames(O)
	  getOwnPropertyNames: $getOwnPropertyNames,
	  // 19.1.2.8 Object.getOwnPropertySymbols(O)
	  getOwnPropertySymbols: $getOwnPropertySymbols
	});
	
	// 24.3.2 JSON.stringify(value [, replacer [, space]])
	$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () {
	  var S = $Symbol();
	  // MS Edge converts symbol values to JSON as {}
	  // WebKit converts symbol values to JSON as null
	  // V8 throws on boxed symbols
	  return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}';
	})), 'JSON', {
	  stringify: function stringify(it) {
	    if (it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
	    var args = [it];
	    var i = 1;
	    var replacer, $replacer;
	    while (arguments.length > i) args.push(arguments[i++]);
	    replacer = args[1];
	    if (typeof replacer == 'function') $replacer = replacer;
	    if ($replacer || !isArray(replacer)) replacer = function (key, value) {
	      if ($replacer) value = $replacer.call(this, key, value);
	      if (!isSymbol(value)) return value;
	    };
	    args[1] = replacer;
	    return _stringify.apply($JSON, args);
	  }
	});
	
	// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
	$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(29)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
	// 19.4.3.5 Symbol.prototype[@@toStringTag]
	setToStringTag($Symbol, 'Symbol');
	// 20.2.1.9 Math[@@toStringTag]
	setToStringTag(Math, 'Math', true);
	// 24.3.3 JSON[@@toStringTag]
	setToStringTag(global.JSON, 'JSON', true);
	
	
	/***/ }),
	/* 112 */
	/***/ (function(module, exports, __webpack_require__) {
	
	exports.f = __webpack_require__(9);
	
	
	/***/ }),
	/* 113 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 19.1.3.1 Object.assign(target, source)
	var $export = __webpack_require__(3);
	
	$export($export.S + $export.F, 'Object', { assign: __webpack_require__(106) });
	
	
	/***/ }),
	/* 114 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 19.1.3.10 Object.is(value1, value2)
	var $export = __webpack_require__(3);
	$export($export.S, 'Object', { is: __webpack_require__(195) });
	
	
	/***/ }),
	/* 115 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 19.1.3.19 Object.setPrototypeOf(O, proto)
	var $export = __webpack_require__(3);
	$export($export.S, 'Object', { setPrototypeOf: __webpack_require__(102).set });
	
	
	/***/ }),
	/* 116 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var dP = __webpack_require__(17).f;
	var FProto = Function.prototype;
	var nameRE = /^\s*function ([^ (]*)/;
	var NAME = 'name';
	
	// 19.2.4.2 name
	NAME in FProto || __webpack_require__(20) && dP(FProto, NAME, {
	  configurable: true,
	  get: function () {
	    try {
	      return ('' + this).match(nameRE)[1];
	    } catch (e) {
	      return '';
	    }
	  }
	});
	
	
	/***/ }),
	/* 117 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var $export = __webpack_require__(3);
	var toIObject = __webpack_require__(25);
	var toLength = __webpack_require__(21);
	
	$export($export.S, 'String', {
	  // 21.1.2.4 String.raw(callSite, ...substitutions)
	  raw: function raw(callSite) {
	    var tpl = toIObject(callSite.raw);
	    var len = toLength(tpl.length);
	    var aLen = arguments.length;
	    var res = [];
	    var i = 0;
	    while (len > i) {
	      res.push(String(tpl[i++]));
	      if (i < aLen) res.push(String(arguments[i]));
	    } return res.join('');
	  }
	});
	
	
	/***/ }),
	/* 118 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var $export = __webpack_require__(3);
	var toAbsoluteIndex = __webpack_require__(53);
	var fromCharCode = String.fromCharCode;
	var $fromCodePoint = String.fromCodePoint;
	
	// length should be 1, old FF problem
	$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
	  // 21.1.2.2 String.fromCodePoint(...codePoints)
	  fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars
	    var res = [];
	    var aLen = arguments.length;
	    var i = 0;
	    var code;
	    while (aLen > i) {
	      code = +arguments[i++];
	      if (toAbsoluteIndex(code, 0x10ffff) !== code) throw RangeError(code + ' is not a valid code point');
	      res.push(code < 0x10000
	        ? fromCharCode(code)
	        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
	      );
	    } return res.join('');
	  }
	});
	
	
	/***/ }),
	/* 119 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var $export = __webpack_require__(3);
	var $at = __webpack_require__(196)(false);
	$export($export.P, 'String', {
	  // 21.1.3.3 String.prototype.codePointAt(pos)
	  codePointAt: function codePointAt(pos) {
	    return $at(this, pos);
	  }
	});
	
	
	/***/ }),
	/* 120 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var $export = __webpack_require__(3);
	
	$export($export.P, 'String', {
	  // 21.1.3.13 String.prototype.repeat(count)
	  repeat: __webpack_require__(121)
	});
	
	
	/***/ }),
	/* 121 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var toInteger = __webpack_require__(52);
	var defined = __webpack_require__(33);
	
	module.exports = function repeat(count) {
	  var str = String(defined(this));
	  var res = '';
	  var n = toInteger(count);
	  if (n < 0 || n == Infinity) throw RangeError("Count can't be negative");
	  for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str;
	  return res;
	};
	
	
	/***/ }),
	/* 122 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	// 21.1.3.18 String.prototype.startsWith(searchString [, position ])
	
	var $export = __webpack_require__(3);
	var toLength = __webpack_require__(21);
	var context = __webpack_require__(75);
	var STARTS_WITH = 'startsWith';
	var $startsWith = ''[STARTS_WITH];
	
	$export($export.P + $export.F * __webpack_require__(76)(STARTS_WITH), 'String', {
	  startsWith: function startsWith(searchString /* , position = 0 */) {
	    var that = context(this, searchString, STARTS_WITH);
	    var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length));
	    var search = String(searchString);
	    return $startsWith
	      ? $startsWith.call(that, search, index)
	      : that.slice(index, index + search.length) === search;
	  }
	});
	
	
	/***/ }),
	/* 123 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 7.2.8 IsRegExp(argument)
	var isObject = __webpack_require__(14);
	var cof = __webpack_require__(37);
	var MATCH = __webpack_require__(9)('match');
	module.exports = function (it) {
	  var isRegExp;
	  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
	};
	
	
	/***/ }),
	/* 124 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])
	
	var $export = __webpack_require__(3);
	var toLength = __webpack_require__(21);
	var context = __webpack_require__(75);
	var ENDS_WITH = 'endsWith';
	var $endsWith = ''[ENDS_WITH];
	
	$export($export.P + $export.F * __webpack_require__(76)(ENDS_WITH), 'String', {
	  endsWith: function endsWith(searchString /* , endPosition = @length */) {
	    var that = context(this, searchString, ENDS_WITH);
	    var endPosition = arguments.length > 1 ? arguments[1] : undefined;
	    var len = toLength(that.length);
	    var end = endPosition === undefined ? len : Math.min(toLength(endPosition), len);
	    var search = String(searchString);
	    return $endsWith
	      ? $endsWith.call(that, search, end)
	      : that.slice(end - search.length, end) === search;
	  }
	});
	
	
	/***/ }),
	/* 125 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	// 21.1.3.7 String.prototype.includes(searchString, position = 0)
	
	var $export = __webpack_require__(3);
	var context = __webpack_require__(75);
	var INCLUDES = 'includes';
	
	$export($export.P + $export.F * __webpack_require__(76)(INCLUDES), 'String', {
	  includes: function includes(searchString /* , position = 0 */) {
	    return !!~context(this, searchString, INCLUDES)
	      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
	  }
	});
	
	
	/***/ }),
	/* 126 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 21.2.5.3 get RegExp.prototype.flags()
	if (__webpack_require__(20) && /./g.flags != 'g') __webpack_require__(17).f(RegExp.prototype, 'flags', {
	  configurable: true,
	  get: __webpack_require__(197)
	});
	
	
	/***/ }),
	/* 127 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// @@match logic
	__webpack_require__(62)('match', 1, function (defined, MATCH, $match) {
	  // 21.1.3.11 String.prototype.match(regexp)
	  return [function match(regexp) {
	    'use strict';
	    var O = defined(this);
	    var fn = regexp == undefined ? undefined : regexp[MATCH];
	    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
	  }, $match];
	});
	
	
	/***/ }),
	/* 128 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// @@replace logic
	__webpack_require__(62)('replace', 2, function (defined, REPLACE, $replace) {
	  // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
	  return [function replace(searchValue, replaceValue) {
	    'use strict';
	    var O = defined(this);
	    var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
	    return fn !== undefined
	      ? fn.call(searchValue, O, replaceValue)
	      : $replace.call(String(O), searchValue, replaceValue);
	  }, $replace];
	});
	
	
	/***/ }),
	/* 129 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// @@split logic
	__webpack_require__(62)('split', 2, function (defined, SPLIT, $split) {
	  'use strict';
	  var isRegExp = __webpack_require__(123);
	  var _split = $split;
	  var $push = [].push;
	  var $SPLIT = 'split';
	  var LENGTH = 'length';
	  var LAST_INDEX = 'lastIndex';
	  if (
	    'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||
	    'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||
	    'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||
	    '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||
	    '.'[$SPLIT](/()()/)[LENGTH] > 1 ||
	    ''[$SPLIT](/.?/)[LENGTH]
	  ) {
	    var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group
	    // based on es5-shim implementation, need to rework it
	    $split = function (separator, limit) {
	      var string = String(this);
	      if (separator === undefined && limit === 0) return [];
	      // If `separator` is not a regex, use native split
	      if (!isRegExp(separator)) return _split.call(string, separator, limit);
	      var output = [];
	      var flags = (separator.ignoreCase ? 'i' : '') +
	                  (separator.multiline ? 'm' : '') +
	                  (separator.unicode ? 'u' : '') +
	                  (separator.sticky ? 'y' : '');
	      var lastLastIndex = 0;
	      var splitLimit = limit === undefined ? 4294967295 : limit >>> 0;
	      // Make `global` and avoid `lastIndex` issues by working with a copy
	      var separatorCopy = new RegExp(separator.source, flags + 'g');
	      var separator2, match, lastIndex, lastLength, i;
	      // Doesn't need flags gy, but they don't hurt
	      if (!NPCG) separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
	      while (match = separatorCopy.exec(string)) {
	        // `separatorCopy.lastIndex` is not reliable cross-browser
	        lastIndex = match.index + match[0][LENGTH];
	        if (lastIndex > lastLastIndex) {
	          output.push(string.slice(lastLastIndex, match.index));
	          // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG
	          // eslint-disable-next-line no-loop-func
	          if (!NPCG && match[LENGTH] > 1) match[0].replace(separator2, function () {
	            for (i = 1; i < arguments[LENGTH] - 2; i++) if (arguments[i] === undefined) match[i] = undefined;
	          });
	          if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));
	          lastLength = match[0][LENGTH];
	          lastLastIndex = lastIndex;
	          if (output[LENGTH] >= splitLimit) break;
	        }
	        if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop
	      }
	      if (lastLastIndex === string[LENGTH]) {
	        if (lastLength || !separatorCopy.test('')) output.push('');
	      } else output.push(string.slice(lastLastIndex));
	      return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
	    };
	  // Chakra, V8
	  } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {
	    $split = function (separator, limit) {
	      return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit);
	    };
	  }
	  // 21.1.3.17 String.prototype.split(separator, limit)
	  return [function split(separator, limit) {
	    var O = defined(this);
	    var fn = separator == undefined ? undefined : separator[SPLIT];
	    return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit);
	  }, $split];
	});
	
	
	/***/ }),
	/* 130 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// @@search logic
	__webpack_require__(62)('search', 1, function (defined, SEARCH, $search) {
	  // 21.1.3.15 String.prototype.search(regexp)
	  return [function search(regexp) {
	    'use strict';
	    var O = defined(this);
	    var fn = regexp == undefined ? undefined : regexp[SEARCH];
	    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
	  }, $search];
	});
	
	
	/***/ }),
	/* 131 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var ctx = __webpack_require__(30);
	var $export = __webpack_require__(3);
	var toObject = __webpack_require__(38);
	var call = __webpack_require__(95);
	var isArrayIter = __webpack_require__(96);
	var toLength = __webpack_require__(21);
	var createProperty = __webpack_require__(77);
	var getIterFn = __webpack_require__(97);
	
	$export($export.S + $export.F * !__webpack_require__(71)(function (iter) { Array.from(iter); }), 'Array', {
	  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
	  from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
	    var O = toObject(arrayLike);
	    var C = typeof this == 'function' ? this : Array;
	    var aLen = arguments.length;
	    var mapfn = aLen > 1 ? arguments[1] : undefined;
	    var mapping = mapfn !== undefined;
	    var index = 0;
	    var iterFn = getIterFn(O);
	    var length, result, step, iterator;
	    if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
	    // if object isn't iterable or it's array with default iterator - use simple case
	    if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) {
	      for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
	        createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);
	      }
	    } else {
	      length = toLength(O.length);
	      for (result = new C(length); length > index; index++) {
	        createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
	      }
	    }
	    result.length = index;
	    return result;
	  }
	});
	
	
	/***/ }),
	/* 132 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var $export = __webpack_require__(3);
	var createProperty = __webpack_require__(77);
	
	// WebKit Array.of isn't generic
	$export($export.S + $export.F * __webpack_require__(23)(function () {
	  function F() { /* empty */ }
	  return !(Array.of.call(F) instanceof F);
	}), 'Array', {
	  // 22.1.2.3 Array.of( ...items)
	  of: function of(/* ...args */) {
	    var index = 0;
	    var aLen = arguments.length;
	    var result = new (typeof this == 'function' ? this : Array)(aLen);
	    while (aLen > index) createProperty(result, index, arguments[index++]);
	    result.length = aLen;
	    return result;
	  }
	});
	
	
	/***/ }),
	/* 133 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
	var $export = __webpack_require__(3);
	
	$export($export.P, 'Array', { copyWithin: __webpack_require__(198) });
	
	__webpack_require__(40)('copyWithin');
	
	
	/***/ }),
	/* 134 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
	var $export = __webpack_require__(3);
	var $find = __webpack_require__(60)(5);
	var KEY = 'find';
	var forced = true;
	// Shouldn't skip holes
	if (KEY in []) Array(1)[KEY](function () { forced = false; });
	$export($export.P + $export.F * forced, 'Array', {
	  find: function find(callbackfn /* , that = undefined */) {
	    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
	  }
	});
	__webpack_require__(40)(KEY);
	
	
	/***/ }),
	/* 135 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
	var $export = __webpack_require__(3);
	var $find = __webpack_require__(60)(6);
	var KEY = 'findIndex';
	var forced = true;
	// Shouldn't skip holes
	if (KEY in []) Array(1)[KEY](function () { forced = false; });
	$export($export.P + $export.F * forced, 'Array', {
	  findIndex: function findIndex(callbackfn /* , that = undefined */) {
	    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
	  }
	});
	__webpack_require__(40)(KEY);
	
	
	/***/ }),
	/* 136 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
	var $export = __webpack_require__(3);
	
	$export($export.P, 'Array', { fill: __webpack_require__(199) });
	
	__webpack_require__(40)('fill');
	
	
	/***/ }),
	/* 137 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.2 Number.isFinite(number)
	var $export = __webpack_require__(3);
	var _isFinite = __webpack_require__(11).isFinite;
	
	$export($export.S, 'Number', {
	  isFinite: function isFinite(it) {
	    return typeof it == 'number' && _isFinite(it);
	  }
	});
	
	
	/***/ }),
	/* 138 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.3 Number.isInteger(number)
	var $export = __webpack_require__(3);
	
	$export($export.S, 'Number', { isInteger: __webpack_require__(139) });
	
	
	/***/ }),
	/* 139 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.3 Number.isInteger(number)
	var isObject = __webpack_require__(14);
	var floor = Math.floor;
	module.exports = function isInteger(it) {
	  return !isObject(it) && isFinite(it) && floor(it) === it;
	};
	
	
	/***/ }),
	/* 140 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.5 Number.isSafeInteger(number)
	var $export = __webpack_require__(3);
	var isInteger = __webpack_require__(139);
	var abs = Math.abs;
	
	$export($export.S, 'Number', {
	  isSafeInteger: function isSafeInteger(number) {
	    return isInteger(number) && abs(number) <= 0x1fffffffffffff;
	  }
	});
	
	
	/***/ }),
	/* 141 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.4 Number.isNaN(number)
	var $export = __webpack_require__(3);
	
	$export($export.S, 'Number', {
	  isNaN: function isNaN(number) {
	    // eslint-disable-next-line no-self-compare
	    return number != number;
	  }
	});
	
	
	/***/ }),
	/* 142 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.1 Number.EPSILON
	var $export = __webpack_require__(3);
	
	$export($export.S, 'Number', { EPSILON: Math.pow(2, -52) });
	
	
	/***/ }),
	/* 143 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.10 Number.MIN_SAFE_INTEGER
	var $export = __webpack_require__(3);
	
	$export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff });
	
	
	/***/ }),
	/* 144 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 20.1.2.6 Number.MAX_SAFE_INTEGER
	var $export = __webpack_require__(3);
	
	$export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff });
	
	
	/***/ }),
	/* 145 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// https://github.com/tc39/Array.prototype.includes
	var $export = __webpack_require__(3);
	var $includes = __webpack_require__(93)(true);
	
	$export($export.P, 'Array', {
	  includes: function includes(el /* , fromIndex = 0 */) {
	    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
	  }
	});
	
	__webpack_require__(40)('includes');
	
	
	/***/ }),
	/* 146 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// https://github.com/tc39/proposal-object-values-entries
	var $export = __webpack_require__(3);
	var $values = __webpack_require__(147)(false);
	
	$export($export.S, 'Object', {
	  values: function values(it) {
	    return $values(it);
	  }
	});
	
	
	/***/ }),
	/* 147 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var getKeys = __webpack_require__(36);
	var toIObject = __webpack_require__(25);
	var isEnum = __webpack_require__(48).f;
	module.exports = function (isEntries) {
	  return function (it) {
	    var O = toIObject(it);
	    var keys = getKeys(O);
	    var length = keys.length;
	    var i = 0;
	    var result = [];
	    var key;
	    while (length > i) if (isEnum.call(O, key = keys[i++])) {
	      result.push(isEntries ? [key, O[key]] : O[key]);
	    } return result;
	  };
	};
	
	
	/***/ }),
	/* 148 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// https://github.com/tc39/proposal-object-values-entries
	var $export = __webpack_require__(3);
	var $entries = __webpack_require__(147)(true);
	
	$export($export.S, 'Object', {
	  entries: function entries(it) {
	    return $entries(it);
	  }
	});
	
	
	/***/ }),
	/* 149 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// https://github.com/tc39/proposal-object-getownpropertydescriptors
	var $export = __webpack_require__(3);
	var ownKeys = __webpack_require__(200);
	var toIObject = __webpack_require__(25);
	var gOPD = __webpack_require__(72);
	var createProperty = __webpack_require__(77);
	
	$export($export.S, 'Object', {
	  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {
	    var O = toIObject(object);
	    var getDesc = gOPD.f;
	    var keys = ownKeys(O);
	    var result = {};
	    var i = 0;
	    var key, desc;
	    while (keys.length > i) {
	      desc = getDesc(O, key = keys[i++]);
	      if (desc !== undefined) createProperty(result, key, desc);
	    }
	    return result;
	  }
	});
	
	
	/***/ }),
	/* 150 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// https://github.com/tc39/proposal-string-pad-start-end
	var $export = __webpack_require__(3);
	var $pad = __webpack_require__(151);
	
	$export($export.P, 'String', {
	  padStart: function padStart(maxLength /* , fillString = ' ' */) {
	    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
	  }
	});
	
	
	/***/ }),
	/* 151 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// https://github.com/tc39/proposal-string-pad-start-end
	var toLength = __webpack_require__(21);
	var repeat = __webpack_require__(121);
	var defined = __webpack_require__(33);
	
	module.exports = function (that, maxLength, fillString, left) {
	  var S = String(defined(that));
	  var stringLength = S.length;
	  var fillStr = fillString === undefined ? ' ' : String(fillString);
	  var intMaxLength = toLength(maxLength);
	  if (intMaxLength <= stringLength || fillStr == '') return S;
	  var fillLen = intMaxLength - stringLength;
	  var stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
	  if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);
	  return left ? stringFiller + S : S + stringFiller;
	};
	
	
	/***/ }),
	/* 152 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// https://github.com/tc39/proposal-string-pad-start-end
	var $export = __webpack_require__(3);
	var $pad = __webpack_require__(151);
	
	$export($export.P, 'String', {
	  padEnd: function padEnd(maxLength /* , fillString = ' ' */) {
	    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
	  }
	});
	
	
	/***/ }),
	/* 153 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var $export = __webpack_require__(3);
	var $task = __webpack_require__(73);
	$export($export.G + $export.B, {
	  setImmediate: $task.set,
	  clearImmediate: $task.clear
	});
	
	
	/***/ }),
	/* 154 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var $iterators = __webpack_require__(78);
	var getKeys = __webpack_require__(36);
	var redefine = __webpack_require__(28);
	var global = __webpack_require__(11);
	var hide = __webpack_require__(29);
	var Iterators = __webpack_require__(45);
	var wks = __webpack_require__(9);
	var ITERATOR = wks('iterator');
	var TO_STRING_TAG = wks('toStringTag');
	var ArrayValues = Iterators.Array;
	
	var DOMIterables = {
	  CSSRuleList: true, // TODO: Not spec compliant, should be false.
	  CSSStyleDeclaration: false,
	  CSSValueList: false,
	  ClientRectList: false,
	  DOMRectList: false,
	  DOMStringList: false,
	  DOMTokenList: true,
	  DataTransferItemList: false,
	  FileList: false,
	  HTMLAllCollection: false,
	  HTMLCollection: false,
	  HTMLFormElement: false,
	  HTMLSelectElement: false,
	  MediaList: true, // TODO: Not spec compliant, should be false.
	  MimeTypeArray: false,
	  NamedNodeMap: false,
	  NodeList: true,
	  PaintRequestList: false,
	  Plugin: false,
	  PluginArray: false,
	  SVGLengthList: false,
	  SVGNumberList: false,
	  SVGPathSegList: false,
	  SVGPointList: false,
	  SVGStringList: false,
	  SVGTransformList: false,
	  SourceBufferList: false,
	  StyleSheetList: true, // TODO: Not spec compliant, should be false.
	  TextTrackCueList: false,
	  TextTrackList: false,
	  TouchList: false
	};
	
	for (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {
	  var NAME = collections[i];
	  var explicit = DOMIterables[NAME];
	  var Collection = global[NAME];
	  var proto = Collection && Collection.prototype;
	  var key;
	  if (proto) {
	    if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);
	    if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
	    Iterators[NAME] = ArrayValues;
	    if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);
	  }
	}
	
	
	/***/ }),
	/* 155 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	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 = function () {
	  _createClass(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;
	    };
	
	    _classCallCheck(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
	   */
	
	
	  _createClass(ViewportColumnsCalculator, [{
	    key: 'calculate',
	    value: function calculate() {
	      var sum = 0;
	      var needReverse = true;
	      var startPositions = [];
	      var columnWidth = void 0;
	
	      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 = 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--;
	          }
	          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;
	      }
	      this.totalTargetWidth = totalWidth;
	
	      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') {
	          totalWidth -= permanentColumnWidth;
	        } else {
	          sumAll += columnWidth;
	        }
	      }
	      var remainingSize = totalWidth - sumAll;
	
	      if (this.stretch === 'all' && remainingSize > 0) {
	        this.stretchAllRatio = totalWidth / sumAll;
	        this.stretchAllColumnsWidth = [];
	        this.needVerifyLastColumnWidth = true;
	      } else if (this.stretch === 'last' && totalWidth !== 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 (width === void 0) {
	        width = ViewportColumnsCalculator.DEFAULT_WIDTH;
	      }
	
	      return width;
	    }
	  }]);
	
	  return ViewportColumnsCalculator;
	}();
	
	exports.default = ViewportColumnsCalculator;
	
	/***/ }),
	/* 156 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	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 = function () {
	  _createClass(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) {
	    _classCallCheck(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
	   */
	
	
	  _createClass(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 = void 0;
	
	      // Calculate the number (start and end index) of rows needed
	      for (var i = 0; i < totalRows; i++) {
	        rowHeight = rowHeightFn(i);
	
	        if (rowHeight === undefined) {
	          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--;
	          }
	          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;
	}();
	
	exports.default = ViewportRowsCalculator;
	
	/***/ }),
	/* 157 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class ColumnFilter
	 */
	var ColumnFilter = function () {
	  /**
	   * @param {Number} offset
	   * @param {Number} total
	   * @param {Number} countTH
	   */
	  function ColumnFilter(offset, total, countTH) {
	    _classCallCheck(this, ColumnFilter);
	
	    this.offset = offset;
	    this.total = total;
	    this.countTH = countTH;
	  }
	
	  /**
	   * @param index
	   * @returns {Number}
	   */
	
	
	  _createClass(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;
	}();
	
	exports.default = ColumnFilter;
	
	/***/ }),
	/* 158 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class RowFilter
	 */
	var RowFilter = function () {
	  /**
	   * @param {Number} offset
	   * @param {Number} total
	   * @param {Number} countTH
	   */
	  function RowFilter(offset, total, countTH) {
	    _classCallCheck(this, RowFilter);
	
	    this.offset = offset;
	    this.total = total;
	    this.countTH = countTH;
	  }
	
	  /**
	   * @param index
	   * @returns {Number}
	   */
	
	
	  _createClass(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;
	}();
	
	exports.default = RowFilter;
	
	/***/ }),
	/* 159 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _object = __webpack_require__(1);
	
	var _string = __webpack_require__(32);
	
	var _event = __webpack_require__(160);
	
	var _event2 = _interopRequireDefault(_event);
	
	var _overlays = __webpack_require__(161);
	
	var _overlays2 = _interopRequireDefault(_overlays);
	
	var _scroll = __webpack_require__(162);
	
	var _scroll2 = _interopRequireDefault(_scroll);
	
	var _settings = __webpack_require__(163);
	
	var _settings2 = _interopRequireDefault(_settings);
	
	var _table = __webpack_require__(164);
	
	var _table2 = _interopRequireDefault(_table);
	
	var _viewport = __webpack_require__(166);
	
	var _viewport2 = _interopRequireDefault(_viewport);
	
	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"); } }
	
	/**
	 * @class Walkontable
	 */
	var Walkontable = function () {
	  /**
	   * @param {Object} settings
	   */
	  function Walkontable(settings) {
	    _classCallCheck(this, Walkontable);
	
	    var originalHeaders = [];
	
	    // this is the namespace for global events
	    this.guid = 'wt_' + (0, _string.randomString)();
	
	    // bootstrap from settings
	    if (settings.cloneSource) {
	      this.cloneSource = settings.cloneSource;
	      this.cloneOverlay = settings.cloneOverlay;
	      this.wtSettings = settings.cloneSource.wtSettings;
	      this.wtTable = new _table2.default(this, settings.table, settings.wtRootElement);
	      this.wtScroll = new _scroll2.default(this);
	      this.wtViewport = settings.cloneSource.wtViewport;
	      this.wtEvent = new _event2.default(this);
	      this.selections = this.cloneSource.selections;
	    } else {
	      this.wtSettings = new _settings2.default(this, settings);
	      this.wtTable = new _table2.default(this, settings.table);
	      this.wtScroll = new _scroll2.default(this);
	      this.wtViewport = new _viewport2.default(this);
	      this.wtEvent = new _event2.default(this);
	      this.selections = this.getSetting('selections');
	      this.wtOverlays = new _overlays2.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}
	   */
	
	
	  _createClass(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);
	    }
	
	    /**
	     * Scroll the viewport to a row at the given index in the data source
	     *
	     * @param {Number} row
	     * @returns {Walkontable}
	     */
	
	  }, {
	    key: 'scrollVertical',
	    value: function scrollVertical(row) {
	      this.wtOverlays.topOverlay.scrollTo(row);
	      this.getSetting('onScrollVertically');
	
	      return this;
	    }
	
	    /**
	     * Scroll the viewport to a column at the given index in the data source
	     *
	     * @param {Number} column
	     * @returns {Walkontable}
	     */
	
	  }, {
	    key: 'scrollHorizontal',
	    value: function scrollHorizontal(column) {
	      this.wtOverlays.leftOverlay.scrollTo(column);
	      this.getSetting('onScrollHorizontally');
	
	      return this;
	    }
	
	    /**
	     * Scrolls the viewport to a cell (rerenders if needed)
	     *
	     * @param {CellCoords} coords
	     * @returns {Walkontable}
	     */
	
	  }, {
	    key: 'scrollViewport',
	    value: function scrollViewport(coords) {
	      this.wtScroll.scrollViewport(coords);
	
	      return this;
	    }
	
	    /**
	     * @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' + (0, _string.toUpperCaseFirst)(key));
	        }
	        allClassNames.push('ht' + (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;
	}();
	
	exports.default = Walkontable;
	
	/***/ }),
	/* 160 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _function = __webpack_require__(35);
	
	var _browser = __webpack_require__(26);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 *
	 */
	function Event(instance) {
	  var that = this;
	  var eventManager = new _eventManager2.default(instance);
	
	  this.instance = instance;
	
	  var dblClickOrigin = [null, null];
	  this.dblClickTimeout = [null, null];
	
	  var onMouseDown = function onMouseDown(event) {
	    var activeElement = document.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 = that.parentCell(realTarget);
	
	    if ((0, _element.hasClass)(realTarget, 'corner')) {
	      that.instance.getSetting('onCellCornerMouseDown', event, realTarget);
	    } else if (cell.TD) {
	      if (that.instance.hasSetting('onCellMouseDown')) {
	        that.instance.getSetting('onCellMouseDown', event, cell.coords, cell.TD, that.instance);
	      }
	    }
	
	    if (event.button !== 2) {
	      // if not right mouse button
	      if (cell.TD) {
	        dblClickOrigin[0] = cell.TD;
	        clearTimeout(that.dblClickTimeout[0]);
	        that.dblClickTimeout[0] = setTimeout(function () {
	          dblClickOrigin[0] = null;
	        }, 1000);
	      }
	    }
	  };
	
	  var onTouchMove = function onTouchMove(event) {
	    that.instance.touchMoving = true;
	  };
	
	  var longTouchTimeout;
	
	  var onTouchStart = function onTouchStart(event) {
	    var container = this;
	
	    eventManager.addEventListener(this, 'touchmove', onTouchMove);
	
	    // Prevent cell selection when scrolling with touch event - not the best solution performance-wise
	    that.checkIfTouchMove = setTimeout(function () {
	      if (that.instance.touchMoving === true) {
	        that.instance.touchMoving = void 0;
	
	        eventManager.removeEventListener('touchmove', onTouchMove, false);
	      }
	
	      onMouseDown(event);
	    }, 30);
	  };
	
	  var onMouseOver = function onMouseOver(event) {
	    var table, td, mainWOT;
	
	    if (that.instance.hasSetting('onCellMouseOver')) {
	      table = that.instance.wtTable.TABLE;
	      td = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table);
	      mainWOT = that.instance.cloneSource || that.instance;
	
	      if (td && td !== mainWOT.lastMouseOver && (0, _element.isChildOf)(td, table)) {
	        mainWOT.lastMouseOver = td;
	
	        that.instance.getSetting('onCellMouseOver', event, that.instance.wtTable.getCoords(td), td, that.instance);
	      }
	    }
	  };
	
	  var onMouseOut = function onMouseOut(event) {
	    var table = void 0;
	    var lastTD = void 0;
	    var nextTD = void 0;
	
	    if (that.instance.hasSetting('onCellMouseOut')) {
	      table = that.instance.wtTable.TABLE;
	      lastTD = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table);
	      nextTD = (0, _element.closestDown)(event.relatedTarget, ['TD', 'TH'], table);
	
	      if (lastTD && lastTD !== nextTD && (0, _element.isChildOf)(lastTD, table)) {
	        that.instance.getSetting('onCellMouseOut', event, that.instance.wtTable.getCoords(lastTD), lastTD, that.instance);
	      }
	    }
	  };
	
	  var onMouseUp = function onMouseUp(event) {
	    if (event.button !== 2) {
	      // if not right mouse button
	      var cell = that.parentCell(event.realTarget);
	
	      if (cell.TD === dblClickOrigin[0] && cell.TD === dblClickOrigin[1]) {
	        if ((0, _element.hasClass)(event.realTarget, 'corner')) {
	          that.instance.getSetting('onCellCornerDblClick', event, cell.coords, cell.TD, that.instance);
	        } else {
	          that.instance.getSetting('onCellDblClick', event, cell.coords, cell.TD, that.instance);
	        }
	
	        dblClickOrigin[0] = null;
	        dblClickOrigin[1] = null;
	      } else if (cell.TD === dblClickOrigin[0]) {
	        that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance);
	
	        dblClickOrigin[1] = cell.TD;
	        clearTimeout(that.dblClickTimeout[1]);
	        that.dblClickTimeout[1] = setTimeout(function () {
	          dblClickOrigin[1] = null;
	        }, 500);
	      } else if (cell.TD && that.instance.hasSetting('onCellMouseUp')) {
	        that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance);
	      }
	    }
	  };
	
	  var onTouchEnd = function onTouchEnd(event) {
	    clearTimeout(longTouchTimeout);
	    // that.instance.longTouch == void 0;
	
	    event.preventDefault();
	    onMouseUp(event);
	
	    // eventManager.removeEventListener(that.instance.wtTable.holder, "mouseup", onMouseUp);
	  };
	
	  eventManager.addEventListener(this.instance.wtTable.holder, 'mousedown', onMouseDown);
	  eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseover', onMouseOver);
	  eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseout', onMouseOut);
	  eventManager.addEventListener(this.instance.wtTable.holder, 'mouseup', onMouseUp);
	
	  // check if full HOT instance, or detached WOT AND run on mobile device
	  if (this.instance.wtTable.holder.parentNode.parentNode && (0, _browser.isMobileBrowser)() && !that.instance.wtTable.isWorkingOnClone()) {
	    var classSelector = '.' + this.instance.wtTable.holder.parentNode.className.split(' ').join('.');
	
	    eventManager.addEventListener(this.instance.wtTable.holder, 'touchstart', function (event) {
	      that.instance.touchApplied = true;
	      if ((0, _element.isChildOf)(event.target, classSelector)) {
	        onTouchStart.call(event.target, event);
	      }
	    });
	    eventManager.addEventListener(this.instance.wtTable.holder, 'touchend', function (event) {
	      that.instance.touchApplied = false;
	      if ((0, _element.isChildOf)(event.target, classSelector)) {
	        onTouchEnd.call(event.target, event);
	      }
	    });
	
	    if (!that.instance.momentumScrolling) {
	      that.instance.momentumScrolling = {};
	    }
	    eventManager.addEventListener(this.instance.wtTable.holder, 'scroll', function (event) {
	      clearTimeout(that.instance.momentumScrolling._timeout);
	
	      if (!that.instance.momentumScrolling.ongoing) {
	        that.instance.getSetting('onBeforeTouchScroll');
	      }
	      that.instance.momentumScrolling.ongoing = true;
	
	      that.instance.momentumScrolling._timeout = setTimeout(function () {
	        if (!that.instance.touchApplied) {
	          that.instance.momentumScrolling.ongoing = false;
	
	          that.instance.getSetting('onAfterMomentumScroll');
	        }
	      }, 200);
	    });
	  }
	
	  eventManager.addEventListener(window, 'resize', function () {
	    if (that.instance.getSetting('stretchH') !== 'none') {
	      that.instance.draw();
	    }
	  });
	
	  this.destroy = function () {
	    clearTimeout(this.dblClickTimeout[0]);
	    clearTimeout(this.dblClickTimeout[1]);
	
	    eventManager.destroy();
	  };
	}
	
	Event.prototype.parentCell = function (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.current.cellRange.highlight; // selections.current is current selected cell
	    cell.TD = this.instance.wtTable.getCell(cell.coords);
	  } else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'area')) {
	    if (this.instance.selections.area.cellRange) {
	      cell.coords = this.instance.selections.area.cellRange.to; // selections.area is area selected cells
	      cell.TD = this.instance.wtTable.getCell(cell.coords);
	    }
	  }
	
	  return cell;
	};
	
	exports.default = Event;
	
	/***/ }),
	/* 161 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _array = __webpack_require__(2);
	
	var _unicode = __webpack_require__(18);
	
	var _browser = __webpack_require__(26);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	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"); } }
	
	/**
	 * @class Overlays
	 */
	var Overlays = function () {
	  /**
	   * @param {Walkontable} wotInstance
	   */
	  function Overlays(wotInstance) {
	    _classCallCheck(this, Overlays);
	
	    this.wot = wotInstance;
	
	    // legacy support
	    this.instance = this.wot;
	    this.eventManager = new _eventManager2.default(this.wot);
	
	    this.wot.update('scrollbarWidth', (0, _element.getScrollbarWidth)());
	    this.wot.update('scrollbarHeight', (0, _element.getScrollbarWidth)());
	
	    this.scrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE);
	
	    this.prepareOverlays();
	
	    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.registerListeners();
	  }
	
	  /**
	   * Prepare overlays based on user settings.
	   *
	   * @returns {Boolean} Returns `true` if changes applied to overlay needs scroll synchronization.
	   */
	
	
	  _createClass(Overlays, [{
	    key: 'prepareOverlays',
	    value: function prepareOverlays() {
	      var syncScroll = false;
	
	      if (this.topOverlay) {
	        syncScroll = this.topOverlay.updateStateOfRendering() || syncScroll;
	      } else {
	        this.topOverlay = _base2.default.createOverlay(_base2.default.CLONE_TOP, this.wot);
	      }
	
	      if (!_base2.default.hasOverlay(_base2.default.CLONE_BOTTOM)) {
	        this.bottomOverlay = {
	          needFullRender: false,
	          updateStateOfRendering: function updateStateOfRendering() {
	            return false;
	          }
	        };
	      }
	      if (!_base2.default.hasOverlay(_base2.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 = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM, this.wot);
	      }
	
	      if (this.leftOverlay) {
	        syncScroll = this.leftOverlay.updateStateOfRendering() || syncScroll;
	      } else {
	        this.leftOverlay = _base2.default.createOverlay(_base2.default.CLONE_LEFT, this.wot);
	      }
	
	      if (this.topOverlay.needFullRender && this.leftOverlay.needFullRender) {
	        if (this.topLeftCornerOverlay) {
	          syncScroll = this.topLeftCornerOverlay.updateStateOfRendering() || syncScroll;
	        } else {
	          this.topLeftCornerOverlay = _base2.default.createOverlay(_base2.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 = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM_LEFT_CORNER, this.wot);
	        }
	      }
	
	      if (this.wot.getSetting('debug') && !this.debug) {
	        this.debug = _base2.default.createOverlay(_base2.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 topOverlayScrollable = this.topOverlay.mainTableScrollableElement;
	      var leftOverlayScrollable = this.leftOverlay.mainTableScrollableElement;
	
	      var listenersToRegister = [];
	      listenersToRegister.push([document.documentElement, 'keydown', function (event) {
	        return _this.onKeyDown(event);
	      }]);
	      listenersToRegister.push([document.documentElement, 'keyup', function () {
	        return _this.onKeyUp();
	      }]);
	      listenersToRegister.push([document, 'visibilitychange', function () {
	        return _this.onKeyUp();
	      }]);
	      listenersToRegister.push([topOverlayScrollable, 'scroll', function (event) {
	        return _this.onTableScroll(event);
	      }]);
	
	      if (topOverlayScrollable !== leftOverlayScrollable) {
	        listenersToRegister.push([leftOverlayScrollable, 'scroll', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	      }
	
	      if (this.topOverlay.needFullRender) {
	        listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'scroll', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	        listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'wheel', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	      }
	
	      if (this.bottomOverlay.needFullRender) {
	        listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'scroll', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	        listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'wheel', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	      }
	
	      if (this.leftOverlay.needFullRender) {
	        listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'scroll', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	        listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'wheel', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	      }
	
	      if (this.topLeftCornerOverlay && this.topLeftCornerOverlay.needFullRender) {
	        listenersToRegister.push([this.topLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	      }
	
	      if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.needFullRender) {
	        listenersToRegister.push([this.bottomLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
	          return _this.onTableScroll(event);
	        }]);
	      }
	
	      if (this.topOverlay.trimmingContainer !== window && this.leftOverlay.trimmingContainer !== window) {
	        // This is necessary?
	        // eventManager.addEventListener(window, 'scroll', (event) => this.refreshAll(event));
	        listenersToRegister.push([window, 'wheel', function (event) {
	          var overlay = void 0;
	          var deltaY = event.wheelDeltaY || event.deltaY;
	          var deltaX = event.wheelDeltaX || event.deltaX;
	
	          if (_this.topOverlay.clone.wtTable.holder.contains(event.realTarget)) {
	            overlay = 'top';
	          } else if (_this.bottomOverlay.clone && _this.bottomOverlay.clone.wtTable.holder.contains(event.realTarget)) {
	            overlay = 'bottom';
	          } else if (_this.leftOverlay.clone.wtTable.holder.contains(event.realTarget)) {
	            overlay = 'left';
	          } else if (_this.topLeftCornerOverlay && _this.topLeftCornerOverlay.clone && _this.topLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) {
	            overlay = 'topLeft';
	          } else if (_this.bottomLeftCornerOverlay && _this.bottomLeftCornerOverlay.clone && _this.bottomLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) {
	            overlay = 'bottomLeft';
	          }
	
	          if (overlay == 'top' && deltaY !== 0 || overlay == 'left' && deltaX !== 0 || overlay == 'bottom' && deltaY !== 0 || (overlay === 'topLeft' || overlay === 'bottomLeft') && (deltaY !== 0 || deltaX !== 0)) {
	
	            event.preventDefault();
	          }
	        }]);
	      }
	
	      while (listenersToRegister.length) {
	        var listener = listenersToRegister.pop();
	        this.eventManager.addEventListener(listener[0], listener[1], listener[2]);
	
	        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) {
	      // if mobile browser, do not update scroll positions, as the overlays are hidden during the scroll
	      if ((0, _browser.isMobileBrowser)()) {
	        return;
	      }
	      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 !== window && target !== window && !event.target.contains(masterVertical) || masterHorizontal !== window && target !== window && !event.target.contains(masterHorizontal)) {
	          return;
	        }
	      }
	
	      if (event.type === 'scroll') {
	        this.syncScrollPositions(event);
	      } else {
	        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
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'translateMouseWheelToScroll',
	    value: function translateMouseWheelToScroll(event) {
	      var topOverlay = this.topOverlay.clone.wtTable.holder;
	      var bottomOverlay = this.bottomOverlay.clone ? this.bottomOverlay.clone.wtTable.holder : null;
	      var leftOverlay = this.leftOverlay.clone.wtTable.holder;
	      var topLeftCornerOverlay = this.topLeftCornerOverlay && this.topLeftCornerOverlay.clone ? this.topLeftCornerOverlay.clone.wtTable.holder : null;
	      var bottomLeftCornerOverlay = this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone ? this.bottomLeftCornerOverlay.clone.wtTable.holder : null;
	      var mouseWheelSpeedRatio = -0.2;
	      var deltaY = event.wheelDeltaY || -1 * event.deltaY;
	      var deltaX = event.wheelDeltaX || -1 * event.deltaX;
	      var parentHolder = null;
	      var eventMockup = { type: 'wheel' };
	      var tempElem = event.target;
	      var delta = null;
	
	      // Fix for extremely slow header scrolling with a mousewheel on Firefox
	      if (event.deltaMode === 1) {
	        deltaY *= 120;
	        deltaX *= 120;
	      }
	
	      while (tempElem != document && tempElem != null) {
	        if (tempElem.className.indexOf('wtHolder') > -1) {
	          parentHolder = tempElem;
	          break;
	        }
	        tempElem = tempElem.parentNode;
	      }
	      eventMockup.target = parentHolder;
	
	      if (parentHolder === topLeftCornerOverlay || parentHolder === bottomLeftCornerOverlay) {
	        this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaX, 'x');
	        this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaY, 'y');
	      } else {
	        if (parentHolder === topOverlay || parentHolder === bottomOverlay) {
	          delta = deltaY;
	        } else if (parentHolder === leftOverlay) {
	          delta = deltaX;
	        }
	
	        this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * delta);
	      }
	
	      return false;
	    }
	
	    /**
	     * Synchronize scroll position between master table and overlay table.
	     *
	     * @private
	     * @param {Event|Object} event
	     * @param {Number} [fakeScrollValue=null]
	     * @param {String} [fakeScrollDirection=null] `x` or `y`.
	     */
	
	  }, {
	    key: 'syncScrollPositions',
	    value: function syncScrollPositions(event) {
	      var fakeScrollValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
	      var fakeScrollDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
	
	      if (this.destroyed) {
	        return;
	      }
	      if (arguments.length === 0) {
	        this.syncScrollWithMaster();
	
	        return;
	      }
	      var masterHorizontal = this.leftOverlay.mainTableScrollableElement;
	      var masterVertical = this.topOverlay.mainTableScrollableElement;
	      var target = event.target;
	      var tempScrollValue = 0;
	      var scrollValueChanged = false;
	      var topOverlay = void 0;
	      var leftOverlay = void 0;
	      var topLeftCornerOverlay = void 0;
	      var bottomLeftCornerOverlay = void 0;
	      var bottomOverlay = void 0;
	      var delegatedScroll = false;
	      var preventOverflow = this.wot.getSetting('preventOverflow');
	
	      if (this.topOverlay.needFullRender) {
	        topOverlay = this.topOverlay.clone.wtTable.holder;
	      }
	
	      if (this.bottomOverlay.needFullRender) {
	        bottomOverlay = this.bottomOverlay.clone.wtTable.holder;
	      }
	
	      if (this.leftOverlay.needFullRender) {
	        leftOverlay = this.leftOverlay.clone.wtTable.holder;
	      }
	
	      if (this.leftOverlay.needFullRender && this.topOverlay.needFullRender) {
	        topLeftCornerOverlay = this.topLeftCornerOverlay.clone.wtTable.holder;
	      }
	
	      if (this.leftOverlay.needFullRender && this.bottomOverlay.needFullRender) {
	        bottomLeftCornerOverlay = this.bottomLeftCornerOverlay.clone.wtTable.holder;
	      }
	
	      if (target === document) {
	        target = window;
	      }
	
	      if (target === masterHorizontal || target === masterVertical) {
	        if (preventOverflow) {
	          tempScrollValue = (0, _element.getScrollLeft)(this.scrollableElement);
	        } else {
	          tempScrollValue = (0, _element.getScrollLeft)(target);
	        }
	
	        // if scrolling the master table - populate the scroll values to both top and left overlays
	        this.horizontalScrolling = true;
	        this.overlayScrollPositions.master.left = tempScrollValue;
	        scrollValueChanged = true;
	
	        if (this.pendingScrollCallbacks.master.left > 0) {
	          this.pendingScrollCallbacks.master.left--;
	        } else {
	          if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) {
	
	            if (fakeScrollValue == null) {
	              this.pendingScrollCallbacks.top.left++;
	            }
	
	            topOverlay.scrollLeft = tempScrollValue;
	            delegatedScroll = masterHorizontal !== window;
	          }
	
	          if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) {
	
	            if (fakeScrollValue == null) {
	              this.pendingScrollCallbacks.bottom.left++;
	            }
	
	            bottomOverlay.scrollLeft = tempScrollValue;
	            delegatedScroll = masterHorizontal !== window;
	          }
	        }
	
	        tempScrollValue = (0, _element.getScrollTop)(target);
	
	        this.verticalScrolling = true;
	        this.overlayScrollPositions.master.top = tempScrollValue;
	        scrollValueChanged = true;
	
	        if (this.pendingScrollCallbacks.master.top > 0) {
	          this.pendingScrollCallbacks.master.top--;
	        } else if (leftOverlay && leftOverlay.scrollTop !== tempScrollValue) {
	          if (fakeScrollValue == null) {
	            this.pendingScrollCallbacks.left.top++;
	          }
	
	          leftOverlay.scrollTop = tempScrollValue;
	          delegatedScroll = masterVertical !== window;
	        }
	      } else if (target === bottomOverlay) {
	        tempScrollValue = (0, _element.getScrollLeft)(target);
	
	        // if scrolling the bottom overlay - populate the horizontal scroll to the master table
	        this.horizontalScrolling = true;
	        this.overlayScrollPositions.bottom.left = tempScrollValue;
	        scrollValueChanged = true;
	
	        if (this.pendingScrollCallbacks.bottom.left > 0) {
	          this.pendingScrollCallbacks.bottom.left--;
	        } else {
	          if (fakeScrollValue == null) {
	            this.pendingScrollCallbacks.master.left++;
	          }
	
	          masterHorizontal.scrollLeft = tempScrollValue;
	
	          if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) {
	            if (fakeScrollValue == null) {
	              this.pendingScrollCallbacks.top.left++;
	            }
	
	            topOverlay.scrollLeft = tempScrollValue;
	            delegatedScroll = masterVertical !== window;
	          }
	        }
	
	        // "fake" scroll value calculated from the mousewheel event
	        if (fakeScrollValue !== null) {
	          scrollValueChanged = true;
	          masterVertical.scrollTop += fakeScrollValue;
	        }
	      } else if (target === topOverlay) {
	        tempScrollValue = (0, _element.getScrollLeft)(target);
	
	        // if scrolling the top overlay - populate the horizontal scroll to the master table
	        this.horizontalScrolling = true;
	        this.overlayScrollPositions.top.left = tempScrollValue;
	        scrollValueChanged = true;
	
	        if (this.pendingScrollCallbacks.top.left > 0) {
	          this.pendingScrollCallbacks.top.left--;
	        } else {
	
	          if (fakeScrollValue == null) {
	            this.pendingScrollCallbacks.master.left++;
	          }
	
	          masterHorizontal.scrollLeft = tempScrollValue;
	        }
	
	        // "fake" scroll value calculated from the mousewheel event
	        if (fakeScrollValue !== null) {
	          scrollValueChanged = true;
	          masterVertical.scrollTop += fakeScrollValue;
	        }
	
	        if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) {
	          if (fakeScrollValue == null) {
	            this.pendingScrollCallbacks.bottom.left++;
	          }
	
	          bottomOverlay.scrollLeft = tempScrollValue;
	          delegatedScroll = masterVertical !== window;
	        }
	      } else if (target === leftOverlay) {
	        tempScrollValue = (0, _element.getScrollTop)(target);
	
	        // if scrolling the left overlay - populate the vertical scroll to the master table
	        if (this.overlayScrollPositions.left.top !== tempScrollValue) {
	          this.verticalScrolling = true;
	          this.overlayScrollPositions.left.top = tempScrollValue;
	          scrollValueChanged = true;
	
	          if (this.pendingScrollCallbacks.left.top > 0) {
	            this.pendingScrollCallbacks.left.top--;
	          } else {
	            if (fakeScrollValue == null) {
	              this.pendingScrollCallbacks.master.top++;
	            }
	
	            masterVertical.scrollTop = tempScrollValue;
	          }
	        }
	
	        // "fake" scroll value calculated from the mousewheel event
	        if (fakeScrollValue !== null) {
	          scrollValueChanged = true;
	          masterVertical.scrollLeft += fakeScrollValue;
	        }
	      } else if (target === topLeftCornerOverlay || target === bottomLeftCornerOverlay) {
	        if (fakeScrollValue !== null) {
	          scrollValueChanged = true;
	
	          if (fakeScrollDirection === 'x') {
	            masterVertical.scrollLeft += fakeScrollValue;
	          } else if (fakeScrollDirection === 'y') {
	            masterVertical.scrollTop += fakeScrollValue;
	          }
	        }
	      }
	
	      if (!this.keyPressed && scrollValueChanged && event.type === 'scroll') {
	        if (this.delegatedScrollCallback) {
	          this.delegatedScrollCallback = false;
	        } else {
	          this.refreshAll();
	        }
	
	        if (delegatedScroll) {
	          this.delegatedScrollCallback = true;
	        }
	      }
	    }
	
	    /**
	     * 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();
	      }
	
	      this.scrollableElement = (0, _element.getScrollableElement)(this.wot.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 totalColumns = this.wot.getSetting('totalColumns');
	      var totalRows = this.wot.getSetting('totalRows');
	      var headerRowSize = this.wot.wtViewport.getRowHeaderWidth();
	      var headerColumnSize = this.wot.wtViewport.getColumnHeaderHeight();
	      var hiderStyle = this.wot.wtTable.hider.style;
	
	      hiderStyle.width = headerRowSize + this.leftOverlay.sumCellSizes(0, totalColumns) + 'px';
	      hiderStyle.height = headerColumnSize + this.topOverlay.sumCellSizes(0, totalRows) + 1 + 'px';
	
	      this.topOverlay.adjustElementsSize(force);
	      this.leftOverlay.adjustElementsSize(force);
	
	      if (this.bottomOverlay.clone) {
	        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, i) {
	        if (!elem) {
	          return;
	        }
	
	        if (elem.clone && elem.clone.wtTable.TABLE.contains(element)) {
	          result = elem.clone;
	        }
	      });
	
	      return result;
	    }
	  }]);
	
	  return Overlays;
	}();
	
	exports.default = Overlays;
	
	/***/ }),
	/* 162 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _number = __webpack_require__(6);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class Scroll
	 */
	var Scroll = function () {
	  /**
	   * @param {Walkontable} wotInstance
	   */
	  function Scroll(wotInstance) {
	    _classCallCheck(this, Scroll);
	
	    this.wot = wotInstance;
	
	    // legacy support
	    this.instance = wotInstance;
	  }
	
	  /**
	   * Scrolls viewport to a cell by minimum number of cells
	   *
	   * @param {CellCoords} coords
	   */
	
	
	  _createClass(Scroll, [{
	    key: 'scrollViewport',
	    value: function scrollViewport(coords) {
	      if (!this.wot.drawn) {
	        return;
	      }
	
	      var _getVariables2 = this._getVariables(),
	          topOverlay = _getVariables2.topOverlay,
	          leftOverlay = _getVariables2.leftOverlay,
	          totalRows = _getVariables2.totalRows,
	          totalColumns = _getVariables2.totalColumns,
	          fixedRowsTop = _getVariables2.fixedRowsTop,
	          fixedRowsBottom = _getVariables2.fixedRowsBottom,
	          fixedColumnsLeft = _getVariables2.fixedColumnsLeft;
	
	      if (coords.row < 0 || coords.row > Math.max(totalRows - 1, 0)) {
	        throw new Error('row ' + coords.row + ' does not exist');
	      }
	
	      if (coords.col < 0 || coords.col > Math.max(totalColumns - 1, 0)) {
	        throw new Error('column ' + coords.col + ' does not exist');
	      }
	
	      if (coords.row >= fixedRowsTop && coords.row < this.getFirstVisibleRow()) {
	        topOverlay.scrollTo(coords.row);
	      } else if (coords.row > this.getLastVisibleRow() && coords.row < totalRows - fixedRowsBottom) {
	        topOverlay.scrollTo(coords.row, true);
	      }
	
	      if (coords.col >= fixedColumnsLeft && coords.col < this.getFirstVisibleColumn()) {
	        leftOverlay.scrollTo(coords.col);
	      } else if (coords.col > this.getLastVisibleColumn()) {
	        leftOverlay.scrollTo(coords.col, true);
	      }
	    }
	
	    /**
	     * 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 _getVariables3 = this._getVariables(),
	          topOverlay = _getVariables3.topOverlay,
	          wtTable = _getVariables3.wtTable,
	          wtViewport = _getVariables3.wtViewport,
	          totalRows = _getVariables3.totalRows,
	          fixedRowsTop = _getVariables3.fixedRowsTop;
	
	      var firstVisibleRow = wtTable.getFirstVisibleRow();
	
	      if (topOverlay.mainTableScrollableElement === window) {
	        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
	        var totalTableHeight = (0, _element.innerHeight)(wtTable.hider);
	        var windowHeight = (0, _element.innerHeight)(window);
	        var windowScrollTop = (0, _element.getScrollTop)(window);
	
	        // 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 _getVariables4 = this._getVariables(),
	          topOverlay = _getVariables4.topOverlay,
	          wtTable = _getVariables4.wtTable,
	          wtViewport = _getVariables4.wtViewport,
	          totalRows = _getVariables4.totalRows;
	
	      var lastVisibleRow = wtTable.getLastVisibleRow();
	
	      if (topOverlay.mainTableScrollableElement === window) {
	        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
	        var windowHeight = (0, _element.innerHeight)(window);
	        var windowScrollTop = (0, _element.getScrollTop)(window);
	
	        // 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 _getVariables5 = this._getVariables(),
	          leftOverlay = _getVariables5.leftOverlay,
	          wtTable = _getVariables5.wtTable,
	          wtViewport = _getVariables5.wtViewport,
	          totalColumns = _getVariables5.totalColumns,
	          fixedColumnsLeft = _getVariables5.fixedColumnsLeft;
	
	      var firstVisibleColumn = wtTable.getFirstVisibleColumn();
	
	      if (leftOverlay.mainTableScrollableElement === window) {
	        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
	        var totalTableWidth = (0, _element.innerWidth)(wtTable.hider);
	        var windowWidth = (0, _element.innerWidth)(window);
	        var windowScrollLeft = (0, _element.getScrollLeft)(window);
	
	        // 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 _getVariables6 = this._getVariables(),
	          leftOverlay = _getVariables6.leftOverlay,
	          wtTable = _getVariables6.wtTable,
	          wtViewport = _getVariables6.wtViewport,
	          totalColumns = _getVariables6.totalColumns;
	
	      var lastVisibleColumn = wtTable.getLastVisibleColumn();
	
	      if (leftOverlay.mainTableScrollableElement === window) {
	        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
	        var windowWidth = (0, _element.innerWidth)(window);
	        var windowScrollLeft = (0, _element.getScrollLeft)(window);
	
	        // 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;
	}();
	
	exports.default = Scroll;
	
	/***/ }),
	/* 163 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _object = __webpack_require__(1);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class Settings
	 */
	var Settings = function () {
	  /**
	   * @param {Walkontable} wotInstance
	   * @param {Object} settings
	   */
	  function Settings(wotInstance, settings) {
	    var _this = this;
	
	    _classCallCheck(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(col) {
	        // return undefined means use default size for the rendered cell content
	      },
	      rowHeight: function rowHeight(row) {
	        // 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,
	      onCellMouseOver: null,
	      onCellMouseOut: null,
	      onCellMouseUp: null,
	
	      //    onCellMouseOut: null,
	      onCellDblClick: null,
	      onCellCornerMouseDown: null,
	      onCellCornerDblClick: null,
	      beforeDraw: null,
	      onDraw: null,
	      onBeforeDrawBorders: null,
	      onScrollVertically: null,
	      onScrollHorizontally: null,
	      onBeforeTouchScroll: null,
	      onAfterMomentumScroll: null,
	      onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(width) {
	        return width;
	      },
	      onModifyRowHeaderWidth: null,
	
	      // constants
	      scrollbarWidth: 10,
	      scrollbarHeight: 10,
	
	      renderAllRows: false,
	      groups: false,
	      rowHeaderWidth: null,
	      columnHeaderHeight: null,
	      headerClassName: null
	    };
	
	    // reference to settings
	    this.settings = {};
	
	    for (var i in this.defaults) {
	      if ((0, _object.hasOwnProperty)(this.defaults, i)) {
	        if (settings[i] !== void 0) {
	          this.settings[i] = settings[i];
	        } else if (this.defaults[i] === void 0) {
	          throw new Error('A required setting "' + i + '" was not provided');
	        } else {
	          this.settings[i] = this.defaults[i];
	        }
	      }
	    }
	  }
	
	  /**
	   * Update settings
	   *
	   * @param {Object} settings
	   * @param {*} value
	   * @returns {Walkontable}
	   */
	
	
	  _createClass(Settings, [{
	    key: 'update',
	    value: function update(settings, value) {
	      if (value === void 0) {
	        // settings is object
	        for (var i in settings) {
	          if ((0, _object.hasOwnProperty)(settings, i)) {
	            this.settings[i] = settings[i];
	          }
	        }
	      } 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;
	}();
	
	exports.default = Settings;
	
	/***/ }),
	/* 164 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _function = __webpack_require__(35);
	
	var _coords = __webpack_require__(49);
	
	var _coords2 = _interopRequireDefault(_coords);
	
	var _range = __webpack_require__(79);
	
	var _range2 = _interopRequireDefault(_range);
	
	var _column = __webpack_require__(157);
	
	var _column2 = _interopRequireDefault(_column);
	
	var _row = __webpack_require__(158);
	
	var _row2 = _interopRequireDefault(_row);
	
	var _tableRenderer = __webpack_require__(165);
	
	var _tableRenderer2 = _interopRequireDefault(_tableRenderer);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 *
	 */
	var Table = function () {
	  /**
	   * @param {Walkontable} wotInstance
	   * @param {HTMLTableElement} table
	   */
	  function Table(wotInstance, table) {
	    var _this = this;
	
	    _classCallCheck(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);
	    };
	  }
	
	  /**
	   *
	   */
	
	
	  _createClass(Table, [{
	    key: 'fixTableDomTree',
	    value: function fixTableDomTree() {
	      this.TBODY = this.TABLE.querySelector('tbody');
	
	      if (!this.TBODY) {
	        this.TBODY = document.createElement('tbody');
	        this.TABLE.appendChild(this.TBODY);
	      }
	      this.THEAD = this.TABLE.querySelector('thead');
	
	      if (!this.THEAD) {
	        this.THEAD = document.createElement('thead');
	        this.TABLE.insertBefore(this.THEAD, this.TBODY);
	      }
	      this.COLGROUP = this.TABLE.querySelector('colgroup');
	
	      if (!this.COLGROUP) {
	        this.COLGROUP = document.createElement('colgroup');
	        this.TABLE.insertBefore(this.COLGROUP, this.THEAD);
	      }
	
	      if (this.wot.getSetting('columnHeaders').length && !this.THEAD.childNodes.length) {
	        this.THEAD.appendChild(document.createElement('TR'));
	      }
	    }
	
	    /**
	     * @param table
	     * @returns {HTMLElement}
	     */
	
	  }, {
	    key: 'createSpreader',
	    value: function createSpreader(table) {
	      var parent = table.parentNode;
	      var spreader = void 0;
	
	      if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
	        spreader = document.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 = void 0;
	
	      if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
	        hider = document.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 = void 0;
	
	      if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
	        holder = document.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()) {
	        this.holder.parentNode.style.position = 'relative';
	
	        if (trimmingElement === window) {
	          var preventOverflow = this.wot.getSetting('preventOverflow');
	
	          if (!preventOverflow) {
	            this.holder.style.overflow = 'visible';
	            this.wtRootElement.style.overflow = 'visible';
	          }
	        } else {
	          this.holder.style.width = (0, _element.getStyle)(trimmingElement, 'width');
	          this.holder.style.height = (0, _element.getStyle)(trimmingElement, 'height');
	          this.holder.style.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,
	          wtOverlays = _wot.wtOverlays,
	          wtViewport = _wot.wtViewport;
	
	      var totalRows = this.instance.getSetting('totalRows');
	      var rowHeaders = this.wot.getSetting('rowHeaders').length;
	      var columnHeaders = this.wot.getSetting('columnHeaders').length;
	      var syncScroll = false;
	
	      if (!this.isWorkingOnClone()) {
	        this.holderOffset = (0, _element.offset)(this.holder);
	        fastDraw = wtViewport.createRenderCalculators(fastDraw);
	
	        if (rowHeaders && !this.wot.getSetting('fixedColumnsLeft')) {
	          var leftScrollPos = wtOverlays.leftOverlay.getScrollPosition();
	          var previousState = this.correctHeaderWidth;
	
	          this.correctHeaderWidth = leftScrollPos > 0;
	
	          if (previousState !== this.correctHeaderWidth) {
	            fastDraw = false;
	          }
	        }
	      }
	
	      if (!this.isWorkingOnClone()) {
	        syncScroll = wtOverlays.prepareOverlays();
	      }
	
	      if (fastDraw) {
	        if (!this.isWorkingOnClone()) {
	          // in case we only scrolled without redraw, update visible rows information in oldRowsCalculator
	          wtViewport.createVisibleCalculators();
	        }
	        if (wtOverlays) {
	          wtOverlays.refresh(true);
	        }
	      } else {
	        if (this.isWorkingOnClone()) {
	          this.tableOffset = this.wot.cloneSource.wtTable.tableOffset;
	        } else {
	          this.tableOffset = (0, _element.offset)(this.TABLE);
	        }
	        var startRow = void 0;
	
	        if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER)) {
	          startRow = 0;
	        } else if (_base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
	          startRow = Math.max(totalRows - this.wot.getSetting('fixedRowsBottom'), 0);
	        } else {
	          startRow = wtViewport.rowsRenderCalculator.startRow;
	        }
	        var startColumn = void 0;
	
	        if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_LEFT) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
	          startColumn = 0;
	        } else {
	          startColumn = wtViewport.columnsRenderCalculator.startColumn;
	        }
	        this.rowFilter = new _row2.default(startRow, totalRows, columnHeaders);
	        this.columnFilter = new _column2.default(startColumn, this.wot.getSetting('totalColumns'), rowHeaders);
	
	        this.alignOverlaysWithTrimmingContainer();
	        this._doDraw(); // creates calculator after draw
	      }
	      this.refreshSelections(fastDraw);
	
	      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();
	      }
	      this.wot.drawn = true;
	
	      return this;
	    }
	  }, {
	    key: '_doDraw',
	    value: function _doDraw() {
	      var wtRenderer = new _tableRenderer2.default(this);
	
	      wtRenderer.render();
	    }
	  }, {
	    key: 'removeClassFromCells',
	    value: function removeClassFromCells(className) {
	      var nodes = this.TABLE.querySelectorAll('.' + className);
	
	      for (var i = 0, len = nodes.length; i < len; i++) {
	        (0, _element.removeClass)(nodes[i], className);
	      }
	    }
	  }, {
	    key: 'refreshSelections',
	    value: function refreshSelections(fastDraw) {
	      if (!this.wot.selections) {
	        return;
	      }
	      var len = this.wot.selections.length;
	
	      if (fastDraw) {
	        for (var i = 0; i < len; i++) {
	          // there was no rerender, so we need to remove classNames by ourselves
	          if (this.wot.selections[i].settings.className) {
	            this.removeClassFromCells(this.wot.selections[i].settings.className);
	          }
	          if (this.wot.selections[i].settings.highlightHeaderClassName) {
	            this.removeClassFromCells(this.wot.selections[i].settings.highlightHeaderClassName);
	          }
	          if (this.wot.selections[i].settings.highlightRowClassName) {
	            this.removeClassFromCells(this.wot.selections[i].settings.highlightRowClassName);
	          }
	          if (this.wot.selections[i].settings.highlightColumnClassName) {
	            this.removeClassFromCells(this.wot.selections[i].settings.highlightColumnClassName);
	          }
	        }
	      }
	      for (var _i = 0; _i < len; _i++) {
	        this.wot.selections[_i].draw(this.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
	     */
	
	  }, {
	    key: 'getCell',
	    value: function getCell(coords) {
	      if (this.isRowBeforeRenderedRows(coords.row)) {
	        // row before rendered rows
	        return -1;
	      } else if (this.isRowAfterRenderedRows(coords.row)) {
	        // row after rendered rows
	        return -2;
	      }
	
	      var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(coords.row)];
	
	      if (TR) {
	        return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(coords.col)];
	      }
	    }
	
	    /**
	     * 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) {
	      if (TD.nodeName !== 'TD' && TD.nodeName !== 'TH') {
	        TD = (0, _element.closest)(TD, ['TD', 'TH']);
	      }
	
	      if (TD === null) {
	        return null;
	      }
	
	      var TR = TD.parentNode;
	      var CONTAINER = TR.parentNode;
	      var row = (0, _element.index)(TR);
	      var col = TD.cellIndex;
	
	      if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_TOP, TD)) {
	        if (CONTAINER.nodeName === 'THEAD') {
	          row -= CONTAINER.childNodes.length;
	        }
	      } else if (CONTAINER === this.THEAD) {
	        row = this.rowFilter.visibleColHeadedRowToSourceRow(row);
	      } else {
	        row = this.rowFilter.renderedToSource(row);
	      }
	
	      if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_LEFT, TD)) {
	        col = this.columnFilter.offsettedTH(col);
	      } else {
	        col = this.columnFilter.visibleRowHeadedColumnToSourceColumn(col);
	      }
	
	      return new _coords2.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: 'isColumnAfterViewport',
	    value: function isColumnAfterViewport(column) {
	      return this.columnFilter && this.columnFilter.sourceToRendered(column) > this.getLastVisibleColumn();
	    }
	  }, {
	    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 columnsCount = this.wot.wtViewport.columnsRenderCalculator.count;
	      var totalColumns = this.wot.getSetting('totalColumns');
	
	      if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) {
	        columnsCount = totalColumns;
	      } else if (this.wot.isOverlayName(_base2.default.CLONE_LEFT) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
	        return Math.min(this.wot.getSetting('fixedColumnsLeft'), totalColumns);
	      }
	
	      return columnsCount;
	    }
	  }, {
	    key: 'getRenderedRowsCount',
	    value: function getRenderedRowsCount() {
	      var rowsCount = this.wot.wtViewport.rowsRenderCalculator.count;
	      var totalRows = this.wot.getSetting('totalRows');
	
	      if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) {
	        rowsCount = totalRows;
	      } else if (this.wot.isOverlayName(_base2.default.CLONE_TOP) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER)) {
	        rowsCount = Math.min(this.wot.getSetting('fixedRowsTop'), totalRows);
	      } else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
	        rowsCount = Math.min(this.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 ((typeof width === 'undefined' ? 'undefined' : _typeof(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 ? 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 = [].concat(_toConsumableArray(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) {
	      if (typeof width !== 'number') {
	        width = this.wot.getSetting('defaultColumnWidth');
	      }
	      if (this.correctHeaderWidth) {
	        width++;
	      }
	
	      return width;
	    }
	  }]);
	
	  return Table;
	}();
	
	exports.default = Table;
	
	/***/ }),
	/* 165 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	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"); } }
	
	var performanceWarningAppeared = false;
	
	/**
	 * @class TableRenderer
	 */
	
	var TableRenderer = function () {
	  /**
	   * @param {WalkontableTable} wtTable
	   */
	  function TableRenderer(wtTable) {
	    _classCallCheck(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;
	  }
	
	  /**
	   *
	   */
	
	
	  _createClass(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 = void 0;
	      var adjusted = false;
	
	      if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.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(_base2.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) {
	            for (var i = 0; i < this.rowHeaderCount; i++) {
	              var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
	
	              width = width == null ? defaultColumnWidth : width;
	
	              this.COLGROUP.childNodes[i].style.width = 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 = _width + 'px';
	          }
	        }
	
	        this.wot.getSetting('onDraw', true);
	      } else if (this.wot.isOverlayName(_base2.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--;
	      }
	    }
	
	    /**
	     * @param {Number} totalRows
	     * @param {Number} rowsToRender
	     * @param {Number} columnsToRender
	     */
	
	  }, {
	    key: 'renderRows',
	    value: function renderRows(totalRows, rowsToRender, columnsToRender) {
	      var lastTD = void 0,
	          TR = void 0;
	      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;
	          console.warn('Performance tip: Handsontable rendered more than 1000 visible rows. Consider limiting the number ' + 'of rendered rows by specifying the table height and/or turning off the "renderAllRows" option.');
	        }
	        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);
	
	        lastTD = this.renderCells(sourceRowIndex, TR, columnsToRender);
	
	        if (!isWorkingOnClone ||
	        // Necessary to refresh oversized row heights after editing cell in overlays
	        this.wot.isOverlayName(_base2.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--;
	            TR.firstChild.style.height = height + 'px';
	          } else {
	            TR.firstChild.style.height = '';
	          }
	        }
	        visibleRowIndex++;
	        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 = void 0;
	      var rowInnerHeight = void 0;
	      var sourceRowIndex = void 0;
	      var currentTr = void 0;
	      var rowHeader = void 0;
	      var totalRows = this.instance.getSetting('totalRows');
	
	      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--;
	        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) {
	          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 = 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 = void 0;
	      var currentHeader = void 0;
	      var currentHeaderHeight = void 0;
	      var columnHeaderHeightSetting = this.wot.getSetting('columnHeaderHeight') || [];
	
	      while (level) {
	        level--;
	
	        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) {
	            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 = void 0;
	      var sourceColIndex = void 0;
	
	      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(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.wtViewport.columnsRenderCalculator.refreshStretching(this.wot.wtViewport.getViewportWidth() - scrollbarCompensation);
	
	      rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);
	
	      if (rowHeaderWidthSetting != null) {
	        for (var i = 0; i < this.rowHeaderCount; i++) {
	          var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
	
	          width = width == null ? defaultColumnWidth : width;
	
	          this.COLGROUP.childNodes[i].style.width = 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 = _width2 + 'px';
	      }
	    }
	
	    /**
	     * @param {HTMLTableCellElement} TR
	     */
	
	  }, {
	    key: 'appendToTbody',
	    value: function appendToTbody(TR) {
	      this.TBODY.appendChild(TR);
	      this.wtTable.tbodyChildrenLength++;
	    }
	
	    /**
	     * @param {Number} rowIndex
	     * @param {HTMLTableRowElement} currentTr
	     * @returns {HTMLTableCellElement}
	     */
	
	  }, {
	    key: 'getOrCreateTrForRow',
	    value: function getOrCreateTrForRow(rowIndex, currentTr) {
	      var TR = void 0;
	
	      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 TR = document.createElement('TR');
	
	      for (var visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) {
	        TR.appendChild(document.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 = document.createElement('TH');
	          TR.appendChild(TH);
	        } else if (TH.nodeName == 'TD') {
	          TH = replaceTdWithTh(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(document.createElement('COL'));
	        this.wtTable.colgroupChildrenLength++;
	      }
	      while (this.wtTable.colgroupChildrenLength > columnCount + this.rowHeaderCount) {
	        this.COLGROUP.removeChild(this.COLGROUP.lastChild);
	        this.wtTable.colgroupChildrenLength--;
	      }
	      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) {
	        for (var i = 0, len = this.columnHeaders.length; i < len; i++) {
	          TR = this.THEAD.childNodes[i];
	
	          if (!TR) {
	            TR = document.createElement('TR');
	            this.THEAD.appendChild(TR);
	          }
	          this.theadChildrenLength = TR.childNodes.length;
	
	          while (this.theadChildrenLength < columnCount + this.rowHeaderCount) {
	            TR.appendChild(document.createElement('TH'));
	            this.theadChildrenLength++;
	          }
	          while (this.theadChildrenLength > columnCount + this.rowHeaderCount) {
	            TR.removeChild(TR.lastChild);
	            this.theadChildrenLength--;
	          }
	        }
	        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 count = TR.childNodes.length;
	
	      while (count < desiredCount) {
	        var TD = document.createElement('TD');
	
	        TR.appendChild(TD);
	        count++;
	      }
	      while (count > desiredCount) {
	        TR.removeChild(TR.lastChild);
	        count--;
	      }
	    }
	
	    /**
	     * @param {Number} columnsToRender
	     */
	
	  }, {
	    key: 'removeRedundantColumns',
	    value: function removeRedundantColumns(columnsToRender) {
	      while (this.wtTable.tbodyChildrenLength > columnsToRender) {
	        this.TBODY.removeChild(this.TBODY.lastChild);
	        this.wtTable.tbodyChildrenLength--;
	      }
	    }
	  }]);
	
	  return TableRenderer;
	}();
	
	function replaceTdWithTh(TD, TR) {
	  var TH = document.createElement('TH');
	
	  TR.insertBefore(TH, TD);
	  TR.removeChild(TD);
	
	  return TH;
	}
	
	function replaceThWithTd(TH, TR) {
	  var TD = document.createElement('TD');
	
	  TR.insertBefore(TD, TH);
	  TR.removeChild(TH);
	
	  return TD;
	}
	
	exports.default = TableRenderer;
	
	/***/ }),
	/* 166 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _object = __webpack_require__(1);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _viewportColumns = __webpack_require__(155);
	
	var _viewportColumns2 = _interopRequireDefault(_viewportColumns);
	
	var _viewportRows = __webpack_require__(156);
	
	var _viewportRows2 = _interopRequireDefault(_viewportRows);
	
	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"); } }
	
	/**
	 * @class Viewport
	 */
	var Viewport = function () {
	  /**
	   * @param wotInstance
	   */
	  function Viewport(wotInstance) {
	    var _this = this;
	
	    _classCallCheck(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 _eventManager2.default(this.wot);
	    this.eventManager.addEventListener(window, 'resize', function () {
	      _this.clientHeight = _this.getWorkspaceHeight();
	    });
	  }
	
	  /**
	   * @returns {number}
	   */
	
	
	  _createClass(Viewport, [{
	    key: 'getWorkspaceHeight',
	    value: function getWorkspaceHeight() {
	      var trimmingContainer = this.instance.wtOverlays.topOverlay.trimmingContainer;
	      var elemHeight = void 0;
	      var height = 0;
	
	      if (trimmingContainer === window) {
	        height = document.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 width = void 0;
	      var totalColumns = this.wot.getSetting('totalColumns');
	      var trimmingContainer = this.instance.wtOverlays.leftOverlay.trimmingContainer;
	      var overflow = void 0;
	      var stretchSetting = this.wot.getSetting('stretchH');
	      var docOffsetWidth = document.documentElement.offsetWidth;
	      var preventOverflow = this.wot.getSetting('preventOverflow');
	
	      if (preventOverflow) {
	        return (0, _element.outerWidth)(this.instance.wtTable.wtRootElement);
	      }
	
	      if (this.wot.getSetting('freezeOverlays')) {
	        width = Math.min(docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth);
	      } else {
	        width = Math.min(this.getContainerFillWidth(), docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth);
	      }
	
	      if (trimmingContainer === window && 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 document.documentElement.clientWidth;
	      }
	
	      if (trimmingContainer !== window) {
	        overflow = (0, _element.getStyle)(this.instance.wtOverlays.leftOverlay.trimmingContainer, 'overflow');
	
	        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 sum = 0;
	
	      while (from < length) {
	        sum += this.wot.wtTable.getColumnWidth(from);
	        from++;
	      }
	
	      return sum;
	    }
	
	    /**
	     * @returns {Number}
	     */
	
	  }, {
	    key: 'getContainerFillWidth',
	    value: function getContainerFillWidth() {
	      if (this.containerWidth) {
	        return this.containerWidth;
	      }
	      var mainContainer = this.instance.wtTable.holder;
	      var fillWidth = void 0;
	      var dummyElement = void 0;
	
	      dummyElement = document.createElement('div');
	      dummyElement.style.width = '100%';
	      dummyElement.style.height = '1px';
	      mainContainer.appendChild(dummyElement);
	      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() {
	      return (0, _element.outerWidth)(this.wot.wtTable.TABLE) || (0, _element.outerWidth)(this.wot.wtTable.TBODY) || (0, _element.outerWidth)(this.wot.wtTable.THEAD); // IE8 reports 0 as <table> offsetWidth;
	    }
	
	    /**
	     * @returns {Number}
	     */
	
	  }, {
	    key: 'getColumnHeaderHeight',
	    value: function getColumnHeaderHeight() {
	      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();
	      var columnHeaderHeight = void 0;
	
	      if (containerHeight === Infinity) {
	        return containerHeight;
	      }
	      columnHeaderHeight = this.getColumnHeaderHeight();
	
	      if (columnHeaderHeight > 0) {
	        containerHeight -= columnHeaderHeight;
	      }
	
	      return containerHeight;
	    }
	
	    /**
	     * @returns {Number}
	     */
	
	  }, {
	    key: 'getRowHeaderWidth',
	    value: function getRowHeaderWidth() {
	      var rowHeadersHeightSetting = this.instance.getSetting('rowHeaderWidth');
	      var rowHeaders = this.instance.getSetting('rowHeaders');
	
	      if (rowHeadersHeightSetting) {
	        this.rowHeaderWidth = 0;
	
	        for (var i = 0, len = rowHeaders.length; i < len; i++) {
	          this.rowHeaderWidth += rowHeadersHeightSetting[i] || rowHeadersHeightSetting;
	        }
	      }
	
	      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();
	      var rowHeaderWidth = void 0;
	
	      if (containerWidth === Infinity) {
	        return containerWidth;
	      }
	      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 _this2 = this;
	
	      var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
	
	      var height = void 0;
	      var pos = void 0;
	      var fixedRowsTop = void 0;
	      var scrollbarHeight = void 0;
	      var fixedRowsBottom = void 0;
	      var fixedRowsHeight = void 0;
	      var totalRows = void 0;
	
	      this.rowHeaderWidth = NaN;
	
	      if (this.wot.wtSettings.settings.renderAllRows) {
	        height = Infinity;
	      } else {
	        height = this.getViewportHeight();
	      }
	      pos = this.wot.wtOverlays.topOverlay.getScrollPosition() - this.wot.wtOverlays.topOverlay.getTableParentOffset();
	
	      if (pos < 0) {
	        pos = 0;
	      }
	      fixedRowsTop = this.wot.getSetting('fixedRowsTop');
	      fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
	      totalRows = this.wot.getSetting('totalRows');
	
	      if (fixedRowsTop) {
	        fixedRowsHeight = this.wot.wtOverlays.topOverlay.sumCellSizes(0, fixedRowsTop);
	        pos += fixedRowsHeight;
	        height -= fixedRowsHeight;
	      }
	
	      if (fixedRowsBottom && this.wot.wtOverlays.bottomOverlay.clone) {
	        fixedRowsHeight = this.wot.wtOverlays.bottomOverlay.sumCellSizes(totalRows - fixedRowsBottom, totalRows);
	
	        height -= fixedRowsHeight;
	      }
	
	      if (this.wot.wtTable.holder.clientHeight === this.wot.wtTable.holder.offsetHeight) {
	        scrollbarHeight = 0;
	      } else {
	        scrollbarHeight = (0, _element.getScrollbarWidth)();
	      }
	
	      return new _viewportRows2.default(height, pos, this.wot.getSetting('totalRows'), function (sourceRow) {
	        return _this2.wot.wtTable.getRowHeight(sourceRow);
	      }, visible ? null : this.wot.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 _this3 = this;
	
	      var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
	
	      var width = this.getViewportWidth();
	      var pos = void 0;
	      var fixedColumnsLeft = void 0;
	
	      this.columnHeaderHeight = NaN;
	
	      pos = this.wot.wtOverlays.leftOverlay.getScrollPosition() - this.wot.wtOverlays.leftOverlay.getTableParentOffset();
	
	      if (pos < 0) {
	        pos = 0;
	      }
	      fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft');
	
	      if (fixedColumnsLeft) {
	        var fixedColumnsWidth = this.wot.wtOverlays.leftOverlay.sumCellSizes(0, fixedColumnsLeft);
	        pos += fixedColumnsWidth;
	        width -= fixedColumnsWidth;
	      }
	      if (this.wot.wtTable.holder.clientWidth !== this.wot.wtTable.holder.offsetWidth) {
	        width -= (0, _element.getScrollbarWidth)();
	      }
	
	      return new _viewportColumns2.default(width, pos, this.wot.getSetting('totalColumns'), function (sourceCol) {
	        return _this3.wot.wtTable.getColumnWidth(sourceCol);
	      }, visible ? null : this.wot.wtSettings.settings.viewportColumnCalculatorOverride, visible, this.wot.getSetting('stretchH'), function (stretchedWidth, column) {
	        return _this3.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;
	
	      if (fastDraw) {
	        var proposedRowsVisibleCalculator = this.createRowsCalculator(true);
	        var proposedColumnsVisibleCalculator = this.createColumnsCalculator(true);
	
	        if (!(this.areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) && this.areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator))) {
	          fastDraw = false;
	        }
	      }
	
	      if (!fastDraw) {
	        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 fastDraw;
	    }
	
	    /**
	     * 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;
	}();
	
	exports.default = Viewport;
	
	/***/ }),
	/* 167 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _event = __webpack_require__(10);
	
	var _object = __webpack_require__(1);
	
	var _browser = __webpack_require__(26);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _coords = __webpack_require__(49);
	
	var _coords2 = _interopRequireDefault(_coords);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	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"); } }
	
	/**
	 *
	 */
	var Border = function () {
	  /**
	   * @param {Walkontable} wotInstance
	   * @param {Object} settings
	   */
	  function Border(wotInstance, settings) {
	    _classCallCheck(this, Border);
	
	    if (!settings) {
	      return;
	    }
	    this.eventManager = new _eventManager2.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: '5px',
	      height: '5px',
	      borderWidth: '2px',
	      borderStyle: 'solid',
	      borderColor: '#FFF'
	    };
	    this.corner = null;
	    this.cornerStyle = null;
	
	    this.createBorders(settings);
	    this.registerListeners();
	  }
	
	  /**
	   * Register all necessary events
	   */
	
	
	  _createClass(Border, [{
	    key: 'registerListeners',
	    value: function registerListeners() {
	      var _this2 = this;
	
	      this.eventManager.addEventListener(document.body, 'mousedown', function () {
	        return _this2.onMouseDown();
	      });
	      this.eventManager.addEventListener(document.body, '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 bounds = parentElement.getBoundingClientRect();
	      // Hide border to prevents selection jumping when fragmentSelection is enabled.
	      parentElement.style.display = 'none';
	
	      function isOutside(event) {
	        if (event.clientY < Math.floor(bounds.top)) {
	          return true;
	        }
	        if (event.clientY > Math.ceil(bounds.top + bounds.height)) {
	          return true;
	        }
	        if (event.clientX < Math.floor(bounds.left)) {
	          return true;
	        }
	        if (event.clientX > Math.ceil(bounds.left + bounds.width)) {
	          return true;
	        }
	      }
	
	      function handler(event) {
	        if (isOutside(event)) {
	          _this.eventManager.removeEventListener(document.body, 'mousemove', handler);
	          parentElement.style.display = 'block';
	        }
	      }
	
	      this.eventManager.addEventListener(document.body, 'mousemove', handler);
	    }
	
	    /**
	     * Create border elements
	     *
	     * @param {Object} settings
	     */
	
	  }, {
	    key: 'createBorders',
	    value: function createBorders(settings) {
	      this.main = document.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 = document.createElement('div');
	        div.className = 'wtBorder ' + (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 ? this.settings[position].width + 'px' : settings.border.width + 'px';
	        style.width = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : 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();
	
	      if (!this.wot.wtTable.bordersHolder) {
	        this.wot.wtTable.bordersHolder = document.createElement('div');
	        this.wot.wtTable.bordersHolder.className = 'htBorders';
	        this.wot.wtTable.spreader.appendChild(this.wot.wtTable.bordersHolder);
	      }
	      this.wot.wtTable.bordersHolder.insertBefore(this.main, this.wot.wtTable.bordersHolder.firstChild);
	    }
	
	    /**
	     * Create multiple selector handler for mobile devices
	     */
	
	  }, {
	    key: 'createMultipleSelectorHandles',
	    value: function createMultipleSelectorHandles() {
	      this.selectionHandles = {
	        topLeft: document.createElement('DIV'),
	        topLeftHitArea: document.createElement('DIV'),
	        bottomRight: document.createElement('DIV'),
	        bottomRightHitArea: document.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: hitAreaWidth + 'px',
	        width: hitAreaWidth + 'px',
	        'border-radius': parseInt(hitAreaWidth / 1.5, 10) + 'px'
	      };
	
	      for (var prop in hitAreaStyle) {
	        if ((0, _object.hasOwnProperty)(hitAreaStyle, prop)) {
	          this.selectionHandles.styles.bottomRightHitArea[prop] = hitAreaStyle[prop];
	          this.selectionHandles.styles.topLeftHitArea[prop] = hitAreaStyle[prop];
	        }
	      }
	
	      var handleStyle = {
	        position: 'absolute',
	        height: width + 'px',
	        width: width + 'px',
	        'border-radius': parseInt(width / 1.5, 10) + 'px',
	        background: '#F5F5FF',
	        border: '1px solid #4285c8'
	      };
	
	      for (var _prop in handleStyle) {
	        if ((0, _object.hasOwnProperty)(handleStyle, _prop)) {
	          this.selectionHandles.styles.bottomRight[_prop] = handleStyle[_prop];
	          this.selectionHandles.styles.topLeft[_prop] = handleStyle[_prop];
	        }
	      }
	      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) {
	      if (this.wot.selections.area.cellRange) {
	        if (row != this.wot.selections.area.cellRange.to.row || col != this.wot.selections.area.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 = parseInt(top - handleWidth, 10) + 'px';
	      this.selectionHandles.styles.topLeft.left = parseInt(left - handleWidth, 10) + 'px';
	
	      this.selectionHandles.styles.topLeftHitArea.top = parseInt(top - hitAreaWidth / 4 * 3, 10) + 'px';
	      this.selectionHandles.styles.topLeftHitArea.left = parseInt(left - hitAreaWidth / 4 * 3, 10) + 'px';
	
	      this.selectionHandles.styles.bottomRight.top = parseInt(top + height, 10) + 'px';
	      this.selectionHandles.styles.bottomRight.left = parseInt(left + width, 10) + 'px';
	
	      this.selectionHandles.styles.bottomRightHitArea.top = parseInt(top + height - hitAreaWidth / 4, 10) + 'px';
	      this.selectionHandles.styles.bottomRightHitArea.left = parseInt(left + width - hitAreaWidth / 4, 10) + 'px';
	
	      if (this.settings.border.multipleSelectionHandlesVisible && this.settings.border.multipleSelectionHandlesVisible()) {
	        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 isMultiple, fromTD, toTD, fromOffset, toOffset, containerOffset, top, minTop, left, minLeft, height, width, fromRow, fromColumn, toRow, toColumn, trimmingContainer, cornerOverlappingContainer, ilen;
	
	      ilen = this.wot.wtTable.getRenderedRowsCount();
	
	      for (var i = 0; i < ilen; i++) {
	        var s = this.wot.wtTable.rowFilter.renderedToSource(i);
	
	        if (s >= corners[0] && s <= corners[2]) {
	          fromRow = s;
	          break;
	        }
	      }
	
	      for (var _i = ilen - 1; _i >= 0; _i--) {
	        var _s = this.wot.wtTable.rowFilter.renderedToSource(_i);
	
	        if (_s >= corners[0] && _s <= corners[2]) {
	          toRow = _s;
	          break;
	        }
	      }
	
	      ilen = this.wot.wtTable.getRenderedColumnsCount();
	
	      for (var _i2 = 0; _i2 < ilen; _i2++) {
	        var _s2 = this.wot.wtTable.columnFilter.renderedToSource(_i2);
	
	        if (_s2 >= corners[1] && _s2 <= corners[3]) {
	          fromColumn = _s2;
	          break;
	        }
	      }
	
	      for (var _i3 = ilen - 1; _i3 >= 0; _i3--) {
	        var _s3 = this.wot.wtTable.columnFilter.renderedToSource(_i3);
	
	        if (_s3 >= corners[1] && _s3 <= corners[3]) {
	          toColumn = _s3;
	          break;
	        }
	      }
	      if (fromRow === void 0 || fromColumn === void 0) {
	        this.disappear();
	
	        return;
	      }
	      isMultiple = fromRow !== toRow || fromColumn !== toColumn;
	      fromTD = this.wot.wtTable.getCell(new _coords2.default(fromRow, fromColumn));
	      toTD = isMultiple ? this.wot.wtTable.getCell(new _coords2.default(toRow, toColumn)) : fromTD;
	      fromOffset = (0, _element.offset)(fromTD);
	      toOffset = isMultiple ? (0, _element.offset)(toTD) : fromOffset;
	      containerOffset = (0, _element.offset)(this.wot.wtTable.TABLE);
	
	      minTop = fromOffset.top;
	      height = toOffset.top + (0, _element.outerHeight)(toTD) - minTop;
	      minLeft = fromOffset.left;
	      width = toOffset.left + (0, _element.outerWidth)(toTD) - minLeft;
	
	      top = minTop - containerOffset.top - 1;
	      left = minLeft - containerOffset.left - 1;
	      var style = (0, _element.getComputedStyle)(fromTD);
	
	      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 = top + 'px';
	      this.topStyle.left = left + 'px';
	      this.topStyle.width = width + 'px';
	      this.topStyle.display = 'block';
	
	      this.leftStyle.top = top + 'px';
	      this.leftStyle.left = left + 'px';
	      this.leftStyle.height = height + 'px';
	      this.leftStyle.display = 'block';
	
	      var delta = Math.floor(this.settings.border.width / 2);
	
	      this.bottomStyle.top = top + height - delta + 'px';
	      this.bottomStyle.left = left + 'px';
	      this.bottomStyle.width = width + 'px';
	      this.bottomStyle.display = 'block';
	
	      this.rightStyle.top = top + 'px';
	      this.rightStyle.left = left + width - delta + 'px';
	      this.rightStyle.height = height + 1 + 'px';
	      this.rightStyle.display = 'block';
	
	      if ((0, _browser.isMobileBrowser)() || !this.hasSetting(this.settings.border.cornerVisible) || this.isPartRange(toRow, toColumn)) {
	        this.cornerStyle.display = 'none';
	      } else {
	        this.cornerStyle.top = top + height - 4 + 'px';
	        this.cornerStyle.left = 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';
	
	        trimmingContainer = (0, _element.getTrimmingContainer)(this.wot.wtTable.TABLE);
	
	        if (toColumn === this.wot.getSetting('totalColumns') - 1) {
	          cornerOverlappingContainer = toTD.offsetLeft + (0, _element.outerWidth)(toTD) + parseInt(this.cornerDefaultStyle.width, 10) / 2 >= (0, _element.innerWidth)(trimmingContainer);
	
	          if (cornerOverlappingContainer) {
	            this.cornerStyle.left = Math.floor(left + width - 3 - parseInt(this.cornerDefaultStyle.width, 10) / 2) + 'px';
	            this.cornerStyle.borderRightWidth = 0;
	          }
	        }
	
	        if (toRow === this.wot.getSetting('totalRows') - 1) {
	          cornerOverlappingContainer = toTD.offsetTop + (0, _element.outerHeight)(toTD) + parseInt(this.cornerDefaultStyle.height, 10) / 2 >= (0, _element.innerHeight)(trimmingContainer);
	
	          if (cornerOverlappingContainer) {
	            this.cornerStyle.top = 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(fromRow, fromColumn, top, left, width, height);
	      }
	    }
	
	    /**
	     * 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';
	      }
	    }
	
	    /**
	     * @param {Function} setting
	     * @returns {*}
	     */
	
	  }, {
	    key: 'hasSetting',
	    value: function hasSetting(setting) {
	      if (typeof setting === 'function') {
	        return setting();
	      }
	
	      return !!setting;
	    }
	  }]);
	
	  return Border;
	}();
	
	exports.default = Border;
	
	/***/ }),
	/* 168 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _unicode = __webpack_require__(18);
	
	var _mixed = __webpack_require__(22);
	
	var _string = __webpack_require__(32);
	
	var _array = __webpack_require__(2);
	
	var _element = __webpack_require__(0);
	
	var _handsontableEditor = __webpack_require__(169);
	
	var _handsontableEditor2 = _interopRequireDefault(_handsontableEditor);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var AutocompleteEditor = _handsontableEditor2.default.prototype.extend();
	
	/**
	 * @private
	 * @editor AutocompleteEditor
	 * @class AutocompleteEditor
	 * @dependencies HandsontableEditor
	 */
	AutocompleteEditor.prototype.init = function () {
	  _handsontableEditor2.default.prototype.init.apply(this, arguments);
	  this.query = null;
	  this.strippedChoices = [];
	  this.rawChoices = [];
	};
	
	AutocompleteEditor.prototype.getValue = function () {
	  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;
	};
	
	AutocompleteEditor.prototype.createElements = function () {
	  _handsontableEditor2.default.prototype.createElements.apply(this, arguments);
	
	  (0, _element.addClass)(this.htContainer, 'autocompleteEditor');
	  (0, _element.addClass)(this.htContainer, window.navigator.platform.indexOf('Mac') === -1 ? '' : 'htMacScroll');
	};
	
	var skipOne = false;
	function onBeforeKeyDown(event) {
	  skipOne = false;
	  var editor = this.getActiveEditor();
	
	  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 (!editor.isOpened()) {
	      timeOffset += 10;
	    }
	
	    if (editor.htEditor) {
	      editor.instance._registerTimeout(setTimeout(function () {
	        editor.queryChoices(editor.TEXTAREA.value);
	        skipOne = true;
	      }, timeOffset));
	    }
	  }
	}
	
	AutocompleteEditor.prototype.prepare = function () {
	  this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
	  _handsontableEditor2.default.prototype.prepare.apply(this, arguments);
	};
	
	AutocompleteEditor.prototype.open = function () {
	  // Ugly fix for handsontable which grab window object for autocomplete scroll listener instead table element.
	  this.TEXTAREA_PARENT.style.overflow = 'auto';
	  _handsontableEditor2.default.prototype.open.apply(this, arguments);
	  this.TEXTAREA_PARENT.style.overflow = '';
	
	  var choicesListHot = this.htEditor.getInstance();
	  var _this = this;
	  var trimDropdown = this.cellProperties.trimDropdown === void 0 ? true : this.cellProperties.trimDropdown;
	
	  this.TEXTAREA.style.visibility = 'visible';
	  this.focus();
	
	  choicesListHot.updateSettings({
	    colWidths: trimDropdown ? [(0, _element.outerWidth)(this.TEXTAREA) - 2] : void 0,
	    width: trimDropdown ? (0, _element.outerWidth)(this.TEXTAREA) + (0, _element.getScrollbarWidth)() + 2 : void 0,
	    afterRenderer: function afterRenderer(TD, row, col, prop, value, cellProperties) {
	      var _this$cellProperties = _this.cellProperties,
	          filteringCaseSensitive = _this$cellProperties.filteringCaseSensitive,
	          allowHtml = _this$cellProperties.allowHtml;
	
	      var indexOfMatch = void 0;
	      var match = void 0;
	
	      value = (0, _mixed.stringify)(value);
	
	      if (value && !allowHtml) {
	        indexOfMatch = filteringCaseSensitive === true ? value.indexOf(this.query) : value.toLowerCase().indexOf(_this.query.toLowerCase());
	
	        if (indexOfMatch !== -1) {
	          match = value.substr(indexOfMatch, _this.query.length);
	          value = value.replace(match, '<strong>' + match + '</strong>');
	        }
	      }
	      TD.innerHTML = value;
	    },
	
	    autoColumnSize: true,
	    modifyColWidth: function modifyColWidth(width, col) {
	      // workaround for <strong> text overlapping the dropdown, not really accurate
	      var autoWidths = this.getPlugin('autoColumnSize').widths;
	
	      if (autoWidths[col]) {
	        width = autoWidths[col];
	      }
	
	      return trimDropdown ? width : width + 15;
	    }
	  });
	
	  // Add additional space for autocomplete holder
	  this.htEditor.view.wt.wtTable.holder.parentNode.style['padding-right'] = (0, _element.getScrollbarWidth)() + 2 + 'px';
	
	  if (skipOne) {
	    skipOne = false;
	  }
	
	  _this.instance._registerTimeout(setTimeout(function () {
	    _this.queryChoices(_this.TEXTAREA.value);
	  }, 0));
	};
	
	AutocompleteEditor.prototype.close = function () {
	  _handsontableEditor2.default.prototype.close.apply(this, arguments);
	};
	AutocompleteEditor.prototype.queryChoices = function (query) {
	  var _this3 = this;
	
	  this.query = query;
	  var source = this.cellProperties.source;
	
	  if (typeof source == 'function') {
	    source.call(this.cellProperties, query, function (choices) {
	      _this3.rawChoices = choices;
	      _this3.updateChoicesList(_this3.stripValuesIfNeeded(choices));
	    });
	  } else if (Array.isArray(source)) {
	    this.rawChoices = source;
	    this.updateChoicesList(this.stripValuesIfNeeded(source));
	  } else {
	    this.updateChoicesList([]);
	  }
	};
	
	AutocompleteEditor.prototype.updateChoicesList = function (choices) {
	  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;
	
	  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.instance.listen();
	  this.TEXTAREA.focus();
	  (0, _element.setCaretPosition)(this.TEXTAREA, pos, pos === endPos ? void 0 : endPos);
	};
	
	AutocompleteEditor.prototype.flipDropdownIfNeeded = function () {
	  var textareaOffset = (0, _element.offset)(this.TEXTAREA);
	  var textareaHeight = (0, _element.outerHeight)(this.TEXTAREA);
	  var dropdownHeight = this.getDropdownHeight();
	  var trimmingContainer = (0, _element.getTrimmingContainer)(this.instance.view.wt.wtTable.TABLE);
	  var trimmingContainerScrollTop = trimmingContainer.scrollTop;
	  var headersHeight = (0, _element.outerHeight)(this.instance.view.wt.wtTable.THEAD);
	  var containerOffset = {
	    row: 0,
	    col: 0
	  };
	
	  if (trimmingContainer !== window) {
	    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;
	};
	
	AutocompleteEditor.prototype.limitDropdownIfNeeded = function (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++;
	    } while (tempHeight < spaceAvailable);
	
	    height = tempHeight - lastRowHeight;
	
	    if (this.htEditor.flipped) {
	      this.htEditor.rootElement.style.top = parseInt(this.htEditor.rootElement.style.top, 10) + dropdownHeight - height + 'px';
	    }
	
	    this.setDropdownHeight(tempHeight - lastRowHeight);
	  }
	};
	
	AutocompleteEditor.prototype.flipDropdown = function (dropdownHeight) {
	  var dropdownStyle = this.htEditor.rootElement.style;
	
	  dropdownStyle.position = 'absolute';
	  dropdownStyle.top = -dropdownHeight + 'px';
	
	  this.htEditor.flipped = true;
	};
	
	AutocompleteEditor.prototype.unflipDropdown = function () {
	  var dropdownStyle = this.htEditor.rootElement.style;
	
	  if (dropdownStyle.position === 'absolute') {
	    dropdownStyle.position = '';
	    dropdownStyle.top = '';
	  }
	
	  this.htEditor.flipped = void 0;
	};
	
	AutocompleteEditor.prototype.updateDropdownHeight = function () {
	  var currentDropdownWidth = this.htEditor.getColWidth(0) + (0, _element.getScrollbarWidth)() + 2;
	  var trimDropdown = this.cellProperties.trimDropdown;
	
	  this.htEditor.updateSettings({
	    height: this.getDropdownHeight(),
	    width: trimDropdown ? void 0 : currentDropdownWidth
	  });
	
	  this.htEditor.view.wt.wtTable.alignOverlaysWithTrimmingContainer();
	};
	
	AutocompleteEditor.prototype.setDropdownHeight = function (height) {
	  this.htEditor.updateSettings({
	    height: height
	  });
	};
	
	AutocompleteEditor.prototype.finishEditing = function (restoreOriginalValue) {
	  if (!restoreOriginalValue) {
	    this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
	  }
	  _handsontableEditor2.default.prototype.finishEditing.apply(this, arguments);
	};
	
	AutocompleteEditor.prototype.highlightBestMatchingChoice = function (index) {
	  if (typeof index === 'number') {
	    this.htEditor.selectCell(index, 0);
	  } else {
	    this.htEditor.deselectCell();
	  }
	};
	
	/**
	 * Filters and sorts by relevance
	 * @param value
	 * @param choices
	 * @param caseSensitive
	 * @returns {Array} array of indexes in original choices array
	 */
	AutocompleteEditor.sortByRelevance = function (value, choices, caseSensitive) {
	  var choicesRelevance = [];
	  var currentItem = void 0;
	  var valueLength = value.length;
	  var valueIndex = void 0;
	  var charsLeft = void 0;
	  var result = [];
	  var i = void 0;
	  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;
	};
	
	AutocompleteEditor.prototype.getDropdownHeight = function () {
	  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;
	};
	
	AutocompleteEditor.prototype.stripValueIfNeeded = function (value) {
	  return this.stripValuesIfNeeded([value])[0];
	};
	
	AutocompleteEditor.prototype.stripValuesIfNeeded = function (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;
	};
	
	AutocompleteEditor.prototype.allowKeyEventPropagation = function (keyCode) {
	  var selected = { row: this.htEditor.getSelectedRange() ? this.htEditor.getSelectedRange().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;
	};
	
	AutocompleteEditor.prototype.discardEditor = function (result) {
	  _handsontableEditor2.default.prototype.discardEditor.apply(this, arguments);
	
	  this.instance.view.render();
	};
	
	exports.default = AutocompleteEditor;
	
	/***/ }),
	/* 169 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _unicode = __webpack_require__(18);
	
	var _object = __webpack_require__(1);
	
	var _element = __webpack_require__(0);
	
	var _event = __webpack_require__(10);
	
	var _textEditor = __webpack_require__(51);
	
	var _textEditor2 = _interopRequireDefault(_textEditor);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var HandsontableEditor = _textEditor2.default.prototype.extend();
	
	/**
	 * @private
	 * @editor HandsontableEditor
	 * @class HandsontableEditor
	 * @dependencies TextEditor
	 */
	HandsontableEditor.prototype.createElements = function () {
	  _textEditor2.default.prototype.createElements.apply(this, arguments);
	
	  var DIV = document.createElement('DIV');
	  DIV.className = 'handsontableEditor';
	  this.TEXTAREA_PARENT.appendChild(DIV);
	
	  this.htContainer = DIV;
	  this.assignHooks();
	};
	
	HandsontableEditor.prototype.prepare = function (td, row, col, prop, value, cellProperties) {
	  _textEditor2.default.prototype.prepare.apply(this, arguments);
	
	  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,
	    afterOnCellMouseDown: function afterOnCellMouseDown(_, coords) {
	      var value = this.getSourceData(coords.row, coords.col);
	
	      // if the value is undefined then it means we don't want to set the value
	      if (value !== void 0) {
	        parent.setValue(value);
	      }
	      parent.instance.destroyEditor();
	    }
	  };
	
	  if (this.cellProperties.handsontable) {
	    (0, _object.extend)(options, cellProperties.handsontable);
	  }
	  this.htOptions = options;
	};
	
	var onBeforeKeyDown = function onBeforeKeyDown(event) {
	  if ((0, _event.isImmediatePropagationStopped)(event)) {
	    return;
	  }
	  var editor = this.getActiveEditor();
	
	  var innerHOT = editor.htEditor.getInstance();
	
	  var rowToSelect;
	  var selectedRow;
	
	  if (event.keyCode == _unicode.KEY_CODES.ARROW_DOWN) {
	    if (!innerHOT.getSelected() && !innerHOT.flipped) {
	      rowToSelect = 0;
	    } else if (innerHOT.getSelected()) {
	      if (innerHOT.flipped) {
	        rowToSelect = innerHOT.getSelected()[0] + 1;
	      } else if (!innerHOT.flipped) {
	        selectedRow = innerHOT.getSelected()[0];
	        var lastRow = innerHOT.countRows() - 1;
	        rowToSelect = Math.min(lastRow, selectedRow + 1);
	      }
	    }
	  } else if (event.keyCode == _unicode.KEY_CODES.ARROW_UP) {
	    if (!innerHOT.getSelected() && innerHOT.flipped) {
	      rowToSelect = innerHOT.countRows() - 1;
	    } else if (innerHOT.getSelected()) {
	      if (innerHOT.flipped) {
	        selectedRow = innerHOT.getSelected()[0];
	        rowToSelect = Math.max(0, selectedRow - 1);
	      } else {
	        selectedRow = innerHOT.getSelected()[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);
	
	      editor.instance.listen();
	      editor.TEXTAREA.focus();
	    }
	  }
	};
	
	HandsontableEditor.prototype.open = function () {
	  this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
	
	  _textEditor2.default.prototype.open.apply(this, arguments);
	
	  if (this.htEditor) {
	    this.htEditor.destroy();
	  }
	  // Construct and initialise a new Handsontable
	  this.htEditor = new this.instance.constructor(this.htContainer, this.htOptions);
	  this.htEditor.init();
	
	  if (this.cellProperties.strict) {
	    this.htEditor.selectCell(0, 0);
	    this.TEXTAREA.style.visibility = 'hidden';
	  } else {
	    this.htEditor.deselectCell();
	    this.TEXTAREA.style.visibility = 'visible';
	  }
	
	  (0, _element.setCaretPosition)(this.TEXTAREA, 0, this.TEXTAREA.value.length);
	};
	
	HandsontableEditor.prototype.close = function () {
	  this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
	  this.instance.listen();
	
	  _textEditor2.default.prototype.close.apply(this, arguments);
	};
	
	HandsontableEditor.prototype.focus = function () {
	  this.instance.listen();
	  _textEditor2.default.prototype.focus.apply(this, arguments);
	};
	
	HandsontableEditor.prototype.beginEditing = function (initialValue) {
	  var onBeginEditing = this.instance.getSettings().onBeginEditing;
	
	  if (onBeginEditing && onBeginEditing() === false) {
	    return;
	  }
	  _textEditor2.default.prototype.beginEditing.apply(this, arguments);
	};
	
	HandsontableEditor.prototype.finishEditing = function (isCancelled, ctrlDown) {
	  if (this.htEditor && this.htEditor.isListening()) {
	    // if focus is still in the HOT editor
	
	    this.instance.listen(); // return the focus to the parent HOT instance
	  }
	
	  if (this.htEditor && this.htEditor.getSelected()) {
	    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 _textEditor2.default.prototype.finishEditing.apply(this, arguments);
	};
	
	HandsontableEditor.prototype.assignHooks = function () {
	  var _this = this;
	
	  this.instance.addHook('afterDestroy', function () {
	    if (_this.htEditor) {
	      _this.htEditor.destroy();
	    }
	  });
	};
	
	exports.default = HandsontableEditor;
	
	/***/ }),
	/* 170 */
	/***/ (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(dateString + "T00:00").getDate())) {
	
	    // Compensate timezone offset
	    return new Date(nativeDate.getTime() + nativeDate.getTimezoneOffset() * 60000);
	  }
	
	  return nativeDate;
	}
	
	/***/ }),
	/* 171 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	/**
	 * 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.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 {
	    global.SheetClip = SheetClip;
	  }
	})(window);
	
	/***/ }),
	/* 172 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.RecordTranslator = undefined;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	exports.registerIdentity = registerIdentity;
	exports.getTranslator = getTranslator;
	
	var _core = __webpack_require__(82);
	
	var _core2 = _interopRequireDefault(_core);
	
	var _object = __webpack_require__(1);
	
	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"); } }
	
	/**
	 * @class RecordTranslator
	 * @util
	 */
	var RecordTranslator = function () {
	  function RecordTranslator(hot) {
	    _classCallCheck(this, RecordTranslator);
	
	    this.hot = hot;
	  }
	
	  /**
	   * Translate physical row index into visual.
	   *
	   * @param {Number} row Physical row index.
	   * @returns {Number} Returns visual row index.
	   */
	
	
	  _createClass(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 = void 0;
	
	      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 = void 0;
	
	      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();
	
	function registerIdentity(identity, hot) {
	  identities.set(identity, hot);
	}
	
	function getTranslator(identity) {
	  var singleton = void 0;
	
	  if (!(identity instanceof _core2.default)) {
	    if (!identities.has(identity)) {
	      throw Error('Record translator was not registered for this object identity');
	    }
	    identity = identities.get(identity);
	  }
	  if (translatorSingletons.has(identity)) {
	    singleton = translatorSingletons.get(identity);
	  } else {
	    singleton = new RecordTranslator(identity);
	    translatorSingletons.set(identity, singleton);
	  }
	
	  return singleton;
	}
	
	/***/ }),
	/* 173 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.registerAsRootInstance = registerAsRootInstance;
	exports.hasValidParameter = hasValidParameter;
	exports.isRootInstance = isRootInstance;
	var holder = exports.holder = new WeakMap();
	
	var rootInstanceSymbol = exports.rootInstanceSymbol = Symbol('rootInstance');
	
	/**
	 * Register an object as a root instance.
	 *
	 * @param  {Object} object An object to associate with root instance flag.
	 */
	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);
	}
	
	/***/ }),
	/* 174 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _mixed = __webpack_require__(22);
	
	var _object = __webpack_require__(1);
	
	/**
	 * @alias Options
	 * @constructor
	 * @description
	
	 * ## Constructor options
	 *
	 * Constructor options are applied using an object literal passed as a second argument to the Handsontable constructor.
	 *
	 * ```js
	 * var hot = new Handsontable(document.getElementById('example1'), {
	 *   data: myArray,
	 *   width: 400,
	 *   height: 300
	 * });
	 * ```
	 *
	 * ---
	 * ## Cascading configuration
	 *
	 * Handsontable 0.9 and newer 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
	 * var hot = new Handsontable(document.getElementById('example'), {
	 *   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.
	   *
	   * @pro
	   * @type {String}
	   * @default 'trial'
	   */
	  licenseKey: 'trial',
	
	  /**
	   * @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](http://docs.handsontable.com/tutorial-data-binding.html#page-reference).
	   *
	   * @type {Array|Function}
	   * @default undefined
	   */
	  data: void 0,
	
	  /**
	   * @description
	   * Defines the structure of a new row when data source is an array of objects.
	   *
	   * See [data-schema](http://docs.handsontable.com/tutorial-data-sources.html#page-data-schema) for examples.
	   *
	   * @type {Object}
	   * @default undefined
	   */
	  dataSchema: void 0,
	
	  /**
	   * Width of the grid. Can be a value or a function that returns a value.
	   *
	   * @type {Number|Function}
	   * @default undefined
	   */
	  width: void 0,
	
	  /**
	   * Height of the grid. Can be a number or a function that returns a number.
	   *
	   * @type {Number|Function}
	   * @default undefined
	   */
	  height: void 0,
	
	  /**
	   * @description
	   * Initial number of rows.
	   *
	   * __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided
	   *
	   * @type {Number}
	   * @default 5
	   */
	  startRows: 5,
	
	  /**
	   * @description
	   * Initial number of columns.
	   *
	   * __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided
	   *
	   * @type {Number}
	   * @default 5
	   */
	  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|Array|Function}
	   * @default null
	   * @example
	   * ```js
	   * ...
	   * // as boolean
	   * rowHeaders: true,
	   * ...
	   *
	   * ...
	   * // as array
	   * rowHeaders: [1, 2, 3],
	   * ...
	   *
	   * ...
	   * // as 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|Array|Function}
	   * @default null
	   * @example
	   * ```js
	   * ...
	   * // as boolean
	   * colHeaders: true,
	   * ...
	   *
	   * ...
	   * // as array
	   * colHeaders: ['A', 'B', 'C'],
	   * ...
	   *
	   * ...
	   * // as 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 {Array|Function|Number|String}
	   * @default undefined
	   * @example
	   * ```js
	   * ...
	   * // as numeric, for each column.
	   * colWidths: 100,
	   * ...
	   *
	   * * ...
	   * // as string, for each column.
	   * colWidths: '100px',
	   * ...
	   *
	   * ...
	   * // as array, based on visual indexes. The rest of the columns have a default width.
	   * colWidths: [100, 120, 90],
	   * ...
	   *
	   * ...
	   * // as 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 ManualRowResize or 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 {Array|Function|Number|String}
	   * @default undefined
	   * @example
	   * ```js
	   * ...
	   * // as numeric, for each row.
	   * rowHeights: 100,
	   * ...
	   *
	   * * ...
	   * // as string, for each row.
	   * rowHeights: '100px',
	   * ...
	   *
	   * ...
	   * // as array, based on visual indexes. The rest of the rows have a default height.
	   * rowHeights: [100, 120, 90],
	   * ...
	   *
	   * ...
	   * // as 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.
	   *
	   * __Notice:__ Using this option sets a fixed number of columns (options `startCols`, `minCols`, `maxCols` will be ignored).
	   *
	   * See [documentation -> datasources.html](http://docs.handsontable.com/tutorial-data-sources.html#page-nested) for examples.
	   *
	   * @type {Array|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',
	   *     format: '0,0.00 $'
	   *   },
	   *   {
	   *     // column options for the second column
	   *     type: 'text',
	   *     readOnly: true
	   *   }
	   * ],
	   * ...
	   *
	   * // or as 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, col, prop) {
	   *   var cellProperties = {};
	   *   var visualRowIndex = this.instance.toVisualRow(row);
	   *   var visualColIndex = this.instance.toVisualColumn(col);
	   *
	   *   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
	   * ...
	   * 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](http://docs.handsontable.com/demo-comments_.html) demo for examples.
	   *
	   * @since 0.11.0
	   * @type {Boolean|Array}
	   * @default false
	   * @example
	   * ```js
	   * ...
	   * comments: [{row: 1, col: 1, comment: {value: "Test comment"}}],
	   * ...
	   * ```
	   */
	  comments: false,
	
	  /**
	   * @description
	   * If `true`, enables the Custom Borders 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](http://docs.handsontable.com/demo-custom-borders.html) demo for examples.
	   *
	   * @since 0.11.0
	   * @type {Boolean|Array}
	   * @default false
	   * @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: ''}
	   * ],
	   * ...
	   * ```
	   */
	  customBorders: false,
	
	  /**
	   * Minimum number of rows. At least that number of rows will be created during initialization.
	   *
	   * @type {Number}
	   * @default 0
	   */
	  minRows: 0,
	
	  /**
	   * Minimum number of columns. At least that number of columns will be created during initialization.
	   *
	   * @type {Number}
	   * @default 0
	   */
	  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
	   */
	  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
	   */
	  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
	   */
	  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
	   */
	  minSpareCols: 0,
	
	  /**
	   * If set to `false`, there won't be an option to insert new rows in the Context Menu.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  allowInsertRow: true,
	
	  /**
	   * If set to `false`, there won't be an option to insert new columns in the Context Menu.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  allowInsertColumn: true,
	
	  /**
	   * If set to `false`, there won't be an option to remove rows in the Context Menu.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  allowRemoveRow: true,
	
	  /**
	   * If set to `false`, there won't be an option to remove columns in the Context Menu.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  allowRemoveColumn: true,
	
	  /**
	   * If true, selection of multiple cells using keyboard or mouse is allowed.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  multiSelect: true,
	
	  /**
	   * 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.
	   *
	   * Possible values: `true` (to enable in all directions), `'vertical'` or `'horizontal'` (to enable in one direction),
	   * `false` (to disable completely). Setting to `true` enables the fillHandle plugin.
	   *
	   * Since 0.23.0 you can pass object to plugin which allows you to add more options for this functionality. If `autoInsertRow`
	   * option is `true`, fill-handler will create new rows till it reaches the last row. It is enabled by default.
	   *
	   * @example
	   * ```js
	   * ...
	   * fillHandle: true // enable plugin in all directions and with autoInsertRow as true
	   * ...
	   * // or
	   * ...
	   * fillHandle: 'vertical' // enable plugin in vertical direction and with autoInsertRow as true
	   * ...
	   * // 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' // 'vertical' or 'horizontal'
	   * }
	   * ```
	   *
	   * @type {Boolean|String|Object}
	   * @default true
	   */
	  fillHandle: true,
	
	  /**
	   * Allows to specify the number of fixed (or *frozen*) rows at the top of the table.
	   *
	   * @type {Number}
	   * @default 0
	   * @example
	   * ```js
	   * fixedRowsTop: 3 // This would freeze the top 3 rows of the table.
	   * ```
	   */
	  fixedRowsTop: 0,
	
	  /**
	   * Allows to specify the number of fixed (or *frozen*) rows at the bottom of the table.
	   *
	   * @pro
	   * @type {Number}
	   * @default 0
	   * @example
	   * ```js
	   * fixedRowsBottom: 3 // This would freeze the top 3 rows of the table.
	   * ```
	   */
	  fixedRowsBottom: 0,
	
	  /**
	   * Allows to specify the number of fixed (or *frozen*) columns on the left of the table.
	   *
	   * @type {Number}
	   * @default 0
	   * @example
	   * ```js
	   * fixedColumnsLeft: 3 // This would freeze the top 3 rows of the table.
	   * ```
	   */
	  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
	   */
	  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
	   */
	  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}
	   */
	  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}
	   * @default {row: 0, col: 1}
	   */
	  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 false
	   */
	  autoWrapRow: false,
	
	  /**
	   * 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 false
	   */
	  autoWrapCol: false,
	
	  /**
	   * @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
	   */
	  persistentState: void 0,
	
	  /**
	   * Class name for all visible rows in the current selection.
	   *
	   * @type {String}
	   * @default undefined
	   * @example
	   * ```js
	   * currentRowClassName: 'currentRow' // This will add a 'currentRow' class name to appropriate table cells.
	   * ```
	   */
	  currentRowClassName: void 0,
	
	  /**
	   * Class name for all visible columns in the current selection.
	   *
	   * @type {String}
	   * @default undefined
	   * @example
	   * ```js
	   * currentColClassName: 'currentColumn' // This will add a 'currentColumn' class name to appropriate table cells.
	   * ```
	   */
	  currentColClassName: void 0,
	
	  /**
	   * Class name for all visible headers in current selection.
	   *
	   * @type {String}
	   * @since 0.27.0
	   * @default 'ht__highlight'
	   * @example
	   * ```js
	   * currentHeaderClassName: 'ht__highlight' // This will add a 'ht__highlight' class name to appropriate table headers.
	   * ```
	   */
	  currentHeaderClassName: 'ht__highlight',
	  /**
	   * Class name for the Handsontable container element.
	   *
	   * @type {String|Array}
	   * @default undefined
	   */
	  className: void 0,
	
	  /**
	   * Class name for all tables inside container element.
	   *
	   * @since 0.17.0
	   * @type {String|Array}
	   * @default undefined
	   */
	  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](http://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'
	   */
	  stretchH: 'none',
	
	  /**
	   * Lets you overwrite the default `isEmptyRow` method, which checks if row at the provided index is empty.
	   *
	   * @type {Function}
	   * @param {Number} row Visual row index.
	   * @returns {Boolean}
	   */
	  isEmptyRow: function isEmptyRow(row) {
	    var col, colLen, value, meta;
	
	    for (col = 0, colLen = this.countCols(); col < colLen; col++) {
	      value = this.getDataAtCell(row, col);
	
	      if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) {
	        if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
	          meta = this.getCellMeta(row, col);
	
	          return (0, _object.isObjectEquals)(this.getSchema()[meta.prop], value);
	        }
	        return false;
	      }
	    }
	
	    return true;
	  },
	
	
	  /**
	   * Lets you overwrite the default `isEmptyCol` method, which checks if column at the provided index is empty.
	   *
	   * @type {Function}
	   * @param {Number} col Visual column index
	   * @returns {Boolean}
	   */
	  isEmptyCol: function isEmptyCol(col) {
	    var row, rowLen, 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
	   */
	  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
	   * @since 0.9.5
	   */
	  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.
	   *
	   * @example
	   * ```js
	   * ...
	   * allowEmpty: true // allow empty values for all cells (whole table)
	   * ...
	   * // or
	   * ...
	   * columns: [
	   *   // allow empty values only for 'date' column
	   *   {data: 'date', dateFormat: 'DD/MM/YYYY', allowEmpty: true}
	   * ]
	   * ...
	   * ```
	   *
	   * @type {Boolean}
	   * @default true
	   * @since 0.23.0
	   */
	  allowEmpty: true,
	
	  /**
	   * CSS class name for cells that did not pass validation.
	   *
	   * @type {String}
	   * @default 'htInvalid'
	   */
	  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 {Mixed}
	   * @default false
	   */
	  placeholder: false,
	
	  /**
	   * CSS class name for cells that have a placeholder in use.
	   *
	   * @type {String}
	   * @default 'htPlaceholder'
	   */
	  placeholderCellClassName: 'htPlaceholder',
	
	  /**
	   * CSS class name for read-only cells.
	   *
	   * @type {String}
	   * @default 'htDimmed'
	   */
	  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](http://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](http://docs.handsontable.com/demo-custom-renderers.html).
	   *
	   * @example
	   * ```js
	   * ...
	   * Handsontable.renderers.registerRenderer('my.renderer', function(instance, TD, row, col, prop, value, cellProperties) {
	   *   TD.innerHTML = value;
	   * });
	   * ...
	   * columns: [
	   *   {
	   *     editor: 'select',
	   *     renderer: 'autocomplete' // as string
	   *   },
	   *   {
	   *     renderer: 'my.renderer' // custom renderer as an alias
	   *   },
	   *   {
	   *     // renderer as custom function
	   *     renderer: function(hotInstance, TD, row, col, prop, value, cellProperties) {
	   *       TD.style.color = 'blue';
	   *       TD.innerHTML = value;
	   *     }
	   *   }
	   * ]
	   * ...
	   * ```
	   *
	   * @type {String|Function}
	   * @default undefined
	   */
	  renderer: void 0,
	
	  /**
	   * CSS class name added to the commented cells.
	   *
	   * @type {String}
	   * @default 'htCommentCell'
	   */
	  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
	   */
	  fragmentSelection: false,
	
	  /**
	   * @description
	   * Make cell [read only](http://docs.handsontable.com/demo-read-only.html).
	   *
	   * @type {Boolean}
	   * @default false
	   */
	  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
	   */
	  skipColumnOnPaste: false,
	
	  /**
	   * @description
	   * Setting to true enables the search plugin (see [demo](http://docs.handsontable.com/demo-search-for-values.html)).
	   *
	   * @type {Boolean}
	   * @default false
	   */
	  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](http://docs.handsontable.com/demo-autocomplete.html)
	   *  * [checkbox](http://docs.handsontable.com/demo-checkbox.html)
	   *  * [date](http://docs.handsontable.com/demo-date.html)
	   *  * [dropdown](http://docs.handsontable.com/demo-dropdown.html)
	   *  * [handsontable](http://docs.handsontable.com/demo-handsontable.html)
	   *  * [numeric](http://docs.handsontable.com/demo-numeric.html)
	   *  * [password](http://docs.handsontable.com/demo-password.html)
	   *  * text
	   *  * [time](http://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.
	   *
	   * @example
	   * ```js
	   * ...
	   * 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);
	   *   }
	   * });
	   * ...
	   * columns: [
	   *   {
	   *     type: 'text'
	   *   },
	   *   {
	   *     type: 'my.type' // an alias to custom type
	   *   },
	   *   {
	   *     type: 'checkbox'
	   *   }
	   * ]
	   * ...
	   * ```
	   *
	   * @type {String}
	   * @default 'text'
	   */
	  type: 'text',
	
	  /**
	   * @description
	   * Make 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
	   * @since 0.10.2
	   */
	  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](http://docs.handsontable.com/demo-autocomplete.html)
	   *  * [checkbox](http://docs.handsontable.com/demo-checkbox.html)
	   *  * [date](http://docs.handsontable.com/demo-date.html)
	   *  * [dropdown](http://docs.handsontable.com/demo-dropdown.html)
	   *  * [handsontable](http://docs.handsontable.com/demo-handsontable.html)
	   *  * [mobile](http://docs.handsontable.com/demo-mobiles-and-tablets.html)
	   *  * [password](http://docs.handsontable.com/demo-password.html)
	   *  * [select](http://docs.handsontable.com/demo-select.html)
	   *  * text
	   *
	   * Or you can [register](http://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`.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [
	   *   {
	   *     editor: 'select'
	   *   },
	   *   {
	   *     editor: false
	   *   }
	   * ]
	   * ...
	   * ```
	   *
	   * @type {String|Function|Boolean}
	   * @default 'text'
	   */
	  editor: void 0,
	
	  /**
	   * @description
	   * Autocomplete definitions. See [autocomplete demo](http://docs.handsontable.com/demo-autocomplete.html) for examples and definitions.
	   *
	   * @type {Array}
	   * @default undefined
	   */
	  autoComplete: 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.
	   *
	   * @since 0.18.0
	   * @type {Number}
	   * @default 10
	   */
	  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.
	   *
	   * @since 0.17.0
	   * @type {Boolean}
	   * @default true
	   */
	  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
	   */
	  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
	   * @since 0.11.0
	   */
	  wordWrap: true,
	
	  /**
	   * CSS class name added to cells with cell meta `wordWrap: false`.
	   *
	   * @type {String}
	   * @default 'htNoWrap'
	   * @since 0.11.0
	   */
	  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](http://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](http://docs.handsontable.com/demo-context-menu.html#page-custom)
	   *
	   * See [the context menu demo](http://docs.handsontable.com/demo-context-menu.html) for examples.
	   *
	   * @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) {
	   *               ...
	   *             }
	   *           },
	   *           ...
	   *         ]
	   *       }
	   *     }
	   *   }
	   * }
	   * ...
	   * ```
	   * @type {Boolean|Array|Object}
	   * @default undefined
	   */
	  contextMenu: void 0,
	
	  /**
	   * @description
	   * Disable or enable the copy/paste functionality.
	   *
	   * @example
	   * ```js
	   * ...
	   * copyPaste: false,
	   * ...
	   * ```
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  copyPaste: true,
	
	  /**
	   * If `true`, undo/redo functionality is enabled.
	   *
	   * @type {Boolean}
	   * @default undefined
	   */
	  undo: void 0,
	
	  /**
	   * @description
	   * Turns on [Column sorting](http://docs.handsontable.com/demo-sorting-data.html).
	   * Can be either a boolean (true/false) or an object with a declared sorting options. See the below example:
	   *
	   * @example
	   * ```js
	   * ...
	   * // as boolean
	   * columnSorting: true
	   * ...
	   * // as a object with initial order (sort ascending column at index 2)
	   * columnSorting: {
	   *   column: 2,
	   *   sortOrder: true, // true = ascending, false = descending, undefined = original order
	   *   sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
	   * }
	   * ...
	   * ```
	   *
	   * @type {Boolean|Object}
	   * @default undefined
	   */
	  columnSorting: void 0,
	
	  /**
	   * @description
	   * Turns on [Manual column move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial
	   * column order, if set to an array of column indexes.
	   *
	   * @example
	   * ```js
	   * ...
	   * // as boolean
	   * 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]
	   * ...
	   * ```
	   *
	   * @type {Boolean|Array}
	   * @default undefined
	   */
	  manualColumnMove: void 0,
	
	  /**
	   * @description
	   * Turns on [Manual column resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial
	   * column resized widths, if set to an array of numbers.
	   *
	   * @example
	   * ```js
	   * ...
	   * // as boolean
	   * manualColumnResize: true
	   * ...
	   * // as a array with initial widths (column at 0 index has 40px and column at 1 index has 50px)
	   * manualColumnResize: [40, 50]
	   * ...
	   * ```
	   *
	   * @type {Boolean|Array}
	   * @default undefined
	   */
	  manualColumnResize: void 0,
	
	  /**
	   * @description
	   * Turns on [Manual row move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial
	   * row order, if set to an array of row indexes.
	   *
	   * @example
	   * ```js
	   * ...
	   * // as 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]
	   * ...
	   * ```
	   *
	   * @type {Boolean|Array}
	   * @default undefined
	   * @since 0.11.0
	   */
	  manualRowMove: void 0,
	
	  /**
	   * @description
	   * Turns on [Manual row resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial
	   * row resized heights, if set to an array of numbers.
	   *
	   * @example
	   * ```js
	   * ...
	   * // as boolean
	   * manualRowResize: true
	   * ...
	   * // as a array with initial heights (row at 0 index has 40px and row at 1 index has 50px)
	   * manualRowResize: [40, 50]
	   * ...
	   * ```
	   *
	   * @type {Boolean|Array}
	   * @default undefined
	   * @since 0.11.0
	   */
	  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.](http://docs.handsontable.com/demo-merge-cells.html)
	   *
	   * @example
	   * ```js
	   * // enables the mergeCells plugin:
	   * margeCells: true
	   * ...
	   * // declares a list of merged sections:
	   * mergeCells: [
	   *   {row: 1, col: 1, rowspan: 3, colspan: 3}, // rowspan and colspan properties declare the width and height of a merged section in cells
	   *   {row: 3, col: 4, rowspan: 2, colspan: 2},
	   *   {row: 5, col: 6, rowspan: 3, colspan: 3}
	   * ]
	   * ```
	   * @type {Boolean|Array}
	   * @default false
	   */
	  mergeCells: false,
	
	  /**
	   * 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'
	   */
	  viewportRowRenderingOffset: 'auto',
	
	  /**
	   * 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'
	   */
	  viewportColumnRenderingOffset: 'auto',
	
	  /**
	   * 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](http://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](http://docs.handsontable.com/demo-data-validation.html).
	   *
	   * @example
	   * ```js
	   * // as a function
	   * columns: [
	   *    {
	   *      validator: function(value, callback) { // validation rules }
	   *    }
	   * ]
	   * ...
	   * // as a regexp
	   * columns: [
	   *    {
	   *      validator: /^[0-9]$/ // regular expression
	   *    }
	   * ]
	   * // as a string
	   * columns: [
	   *    {
	   *      validator: 'numeric'
	   *    }
	   * ]
	   * ```
	   * @type {Function|RegExp|String}
	   * @default undefined
	   * @since 0.9.5
	   */
	  validator: void 0,
	
	  /**
	   * @description
	   * Disable 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.
	   *
	   * @type {Boolean|String|Array}
	   * @default false
	   * @since 0.13.2
	   * @example
	   * ```js
	   * ...
	   * // as boolean
	   * disableVisualSelection: true,
	   * ...
	   *
	   * ...
	   * // as string ('current' or 'area')
	   * disableVisualSelection: 'current',
	   * ...
	   *
	   * ...
	   * // as array
	   * disableVisualSelection: ['current', 'area'],
	   * ...
	   * ```
	   */
	  disableVisualSelection: false,
	
	  /**
	   * @description
	   * Set whether to display the current sorting order indicator (a triangle icon in the column header, specifying the sorting order).
	   *
	   * @type {Boolean}
	   * @default false
	   * @since 0.15.0-beta3
	   */
	  sortIndicator: void 0,
	
	  /**
	   * Disable or enable ManualColumnFreeze plugin.
	   *
	   * @type {Boolean}
	   * @default false
	   */
	  manualColumnFreeze: void 0,
	
	  /**
	   * @description
	   * Defines whether Handsontable should trim the whitespace at the beginning and the end of the cell contents.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  trimWhitespace: true,
	
	  settings: void 0,
	
	  /**
	   * @description
	   * Defines data source for Autocomplete or Dropdown cell types.
	   *
	   * @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('http://example.com/query?q=' + query, function(response) {
	   *       callback(response.items);
	   *     })
	   *   }
	   * }]
	   * ...
	   * ```
	   *
	   * @type {Array|Function}
	   * @default undefined
	   */
	  source: void 0,
	
	  /**
	   * @description
	   * Defines the column header name.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *     title: 'First name',
	   *     type: 'text',
	   *   },
	   *   {
	   *     title: 'Last name',
	   *     type: 'text',
	   *   }]
	   * ...
	   * ```
	   *
	   * @type {String}
	   * @default undefined
	   */
	  title: void 0,
	
	  /**
	   * Data template for `'checkbox'` type when checkbox is checked.
	   *
	   * @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'.
	   * ```
	   * @type {Boolean|String}
	   * @default true
	   */
	  checkedTemplate: void 0,
	
	  /**
	   * Data template for `'checkbox'` type when checkbox is unchecked.
	   *
	   * @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'.
	   * ```
	   * @type {Boolean|String}
	   * @default false
	   */
	  uncheckedTemplate: void 0,
	
	  /**
	   * @description
	   * Object which describes if renderer should create checkbox element with label element as a parent. Option desired for
	   * [checkbox](http://docs.handsontable.com/demo-checkbox.html)-typed cells.
	   *
	   * By default the [checkbox](http://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.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'checkbox',
	   *   label: {position: 'after', value: 'My label: '}
	   * }]
	   * ...
	   * ```
	   *
	   * @since 0.19.0
	   * @type {Object}
	   * @default undefined
	   */
	  label: void 0,
	
	  /**
	   * Display format. See [numbrojs](http://numbrojs.com). This option is desired for
	   * [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells.
	   *
	   * Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'numeric',
	   *   format: '0,00'
	   * }]
	   * ...
	   * ```
	   *
	   * @type {String}
	   * @default '0'
	   */
	  format: void 0,
	
	  /**
	   * Language display format. See [numbrojs](http://numbrojs.com/languages.html#supported-languages). This option is desired for
	   * [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells.
	   *
	   * Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'numeric',
	   *   language: 'en-US'
	   * }]
	   * ...
	   * ```
	   *
	   * @type {String}
	   * @default 'en-US'
	   */
	  language: void 0,
	
	  /**
	   * @description
	   * Data source for [select](http://docs.handsontable.com/demo-select.html)-typed cells.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   editor: 'select',
	   *   selectOptions: ['A', 'B', 'C'],
	   * }]
	   * ...
	   * ```
	   *
	   * @type {Array}
	   */
	  selectOptions: void 0,
	
	  /**
	   * Enables or disables the 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 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.
	   * `syncLimit` option is available since 0.16.0.
	   *
	   * You can also use the `useHeaders` option to take the column headers with into calculation.
	   *
	   * @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 calculation the column width
	   * autoColumnSize: {useHeaders: true},
	   * ...
	   *
	   * ```
	   *
	   * @type {Object|Boolean}
	   * @default {syncLimit: 50}
	   */
	  autoColumnSize: void 0,
	
	  /**
	   * Enables or disables 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.
	   * `syncLimit` options is available since 0.16.0.
	   *
	   * @example
	   * ```js
	   * ...
	   * // as number (300 columns in sync, rest async)
	   * autoRowSize: {syncLimit: 300},
	   * ...
	   *
	   * ...
	   * // as string (percent)
	   * autoRowSize: {syncLimit: '40%'},
	   * ...
	   * ```
	   * @type {Object|Boolean}
	   * @default {syncLimit: 1000}
	   */
	  autoRowSize: void 0,
	
	  /**
	   * Date validation format.
	   *
	   * Option desired for `'date'` - typed cells.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'date',
	   *   dateFormat: 'MM/DD/YYYY'
	   * }]
	   * ...
	   * ```
	   *
	   * @type {String}
	   * @default 'DD/MM/YYYY'
	   */
	  dateFormat: void 0,
	
	  /**
	   * If `true` then dates will be automatically formatted to match the desired format.
	   *
	   * Option desired for `'date'`-typed typed cells.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'date',
	   *   dateFormat: 'YYYY-MM-DD',
	   *   correctFormat: true
	   * }]
	   * ...
	   * ```
	   *
	   * @type {Boolean}
	   * @default false
	   */
	  correctFormat: false,
	
	  /**
	   * Definition of default value which will fill the empty cells.
	   *
	   * Option desired for `'date'`-typed cells.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'date',
	   *   defaultData: '2015-02-02'
	   * }]
	   * ...
	   * ```
	   *
	   * @type {String}
	   */
	  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.
	   *
	   * Option desired for `autocomplete`-typed cells.
	   *
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'autocomplete',
	   *   source: ['A', 'B', 'C'],
	   *   strict: true
	   * }]
	   * ...
	   * ```
	   *
	   * @type {Boolean}
	   */
	  strict: void 0,
	
	  /**
	   * @description
	   * If typed `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.
	   *
	   * Option desired for `'autocomplete'`-typed cells.
	   * @example
	   * ```js
	   * ...
	   * columns: [{
	   *   type: 'autocomplete',
	   *   allowHtml: true,
	   *   source: ['<b>foo</b>', '<b>bar</b>']
	   * }]
	   * ...
	   * ```
	   * @type {Boolean}
	   * @default false
	   */
	  allowHtml: false,
	
	  /**
	   * If typed `true` then virtual rendering mechanism for handsontable will be disabled.
	   *
	   * @type {Boolean}
	   */
	  renderAllRows: void 0,
	
	  /**
	   * Prevents table to overlap outside the parent element. If `'horizontal'` option is chosen then table will appear horizontal
	   * scrollbar in case where parent's width is narrower then table's width.
	   *
	   * Possible values:
	   *  * `false` - Disables functionality (Default option).
	   *  * `horizontal` - Prevents horizontal overflow table.
	   *  * `vertical` - Prevents vertical overflow table (Not implemented yet).
	   *
	   * @since 0.20.3
	   * @example
	   * ```js
	   * ...
	   * preventOverflow: 'horizontal'
	   * ...
	   * ```
	   *
	   * @type {String|Boolean}
	   */
	  preventOverflow: false,
	
	  /**
	   * @description
	   * Plugin allowing 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.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean|String}
	   * @example
	   *
	   * ```js
	   * ...
	   * var hot = new Handsontable(document.getElementById('example'), {
	   *   date: getData(),
	   *   bindRowsWithHeaders: true
	   * });
	   * ...
	   * ```
	   *
	   */
	  bindRowsWithHeaders: void 0,
	
	  /**
	   * @description
	   * The 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.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean|Array}
	   * @example
	   * ```js
	   * ...
	   *  collapsibleColumns: [
	   *    {row: -4, col: 1, collapsible: true},
	   *    {row: -3, col: 5, collapsible: true}
	   *  ]
	   * ...
	   * // or
	   * ...
	   *  collapsibleColumns: true
	   * ...
	   * ```
	   */
	  collapsibleColumns: void 0,
	
	  /**
	   * @description
	   * Allows making pre-defined calculations on the cell values and display the results within Handsontable.
	   * See the demo for more information.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Object}
	   */
	  columnSummary: void 0,
	
	  /**
	   * This plugin allows adding a configurable dropdown menu to the table's column headers.
	   * The dropdown menu acts like the Context Menu, but is triggered by clicking the button in the header.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean|Object|Array}
	   */
	  dropdownMenu: void 0,
	
	  /**
	   * The filters plugin.
	   * It allows filtering the table data either by the built-in component or with the API.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean}
	   */
	  filters: void 0,
	
	  /**
	   * It allows Handsontable to process formula expressions defined in the provided data.
	   *
	   * @pro
	   * @since 1.7.0
	   * @type {Boolean}
	   */
	  formulas: void 0,
	
	  /**
	   * @description
	   * GanttChart plugin enables a possibility to create a Gantt chart using a Handsontable instance.
	   * In this case, the whole table becomes read-only.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Object}
	   */
	  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).
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean|Object}
	   */
	  headerTooltips: void 0,
	
	  /**
	   * Plugin allowing hiding of certain columns.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean|Object}
	   */
	  hiddenColumns: void 0,
	
	  /**
	   * @description
	   * Plugin allowing hiding of certain rows.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean|Object}
	   */
	  hiddenRows: void 0,
	
	  /**
	   * @description
	   * Allows creating a nested header structure, using the HTML's colspan attribute.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Array}
	   */
	  nestedHeaders: void 0,
	
	  /**
	   * @description
	   * Plugin allowing hiding of certain rows.
	   *
	   * @pro
	   * @since 1.0.0-beta1
	   * @type {Boolean|Array}
	   */
	  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.
	   *
	   * @since 0.22.0
	   * @type {Number|Array}
	   */
	  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.
	   *
	   * @since 0.22.0
	   * @type {Number|Array}
	   */
	  columnHeaderHeight: void 0,
	
	  /**
	   * @description
	   * Enabling this 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 false
	   */
	  observeChanges: void 0,
	
	  /**
	   * @description
	   * When passed to the `column` property, allows specifying a custom sorting function for the desired column.
	   *
	   * @since 0.24.0
	   * @type {Function}
	   * @example
	   * ```js
	   * columns: [
	   *   {
	   *     sortFunction: function(sortOrder) {
	   *        return function(a, b) {
	   *          // sorting function body.
	   *          //
	   *          // Function parameters:
	   *          // sortOrder: If true, the order is ascending, if false - descending. undefined = original order
	   *          // a, b: Two compared elements. These are 2-element arrays, with the first element being the row index, the second - cell value.
	   *        }
	   *     }
	   *   }
	   * ]
	   * ```
	   */
	  sortFunction: 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).
	   *
	   * Option desired for cells of the `'autocomplete'` type.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  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.
	   *
	   * @type {Boolean}
	   * @default true
	   */
	  filter: true,
	
	  /**
	   * If defined as 'true', filtering in the Autocomplete Editor will be case-sensitive.
	   *
	   * @type {Boolean}
	   * @default: false
	   */
	  filteringCaseSensitive: false
	};
	
	exports.default = DefaultSettings;
	
	/***/ }),
	/* 175 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _object = __webpack_require__(1);
	
	var _number = __webpack_require__(6);
	
	var _mixed = __webpack_require__(22);
	
	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; }
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class SamplesGenerator
	 * @util
	 */
	var SamplesGenerator = function () {
	  _createClass(SamplesGenerator, null, [{
	    key: 'SAMPLE_COUNT',
	
	    /**
	     * Number of samples to take of each value length.
	     *
	     * @type {Number}
	     */
	    get: function get() {
	      return 3;
	    }
	  }]);
	
	  function SamplesGenerator(dataFactory) {
	    _classCallCheck(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}
	   */
	
	
	  _createClass(SamplesGenerator, [{
	    key: 'getSampleCount',
	    value: function getSampleCount() {
	      if (this.customSampleCount) {
	        return this.customSampleCount;
	      }
	      return SamplesGenerator.SAMPLE_COUNT;
	    }
	  }, {
	    key: 'setSampleCount',
	
	
	    /**
	     * Set the sample count.
	     *
	     * @param {Number} sampleCount Number of samples to be collected.
	     */
	    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();
	
	      if (typeof specifierRange === 'number') {
	        specifierRange = { from: specifierRange, to: specifierRange };
	      }
	      (0, _number.rangeEach)(specifierRange.from, specifierRange.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;
	
	      var samples = new Map();
	      var sampledValues = [];
	      var length = void 0;
	
	      (0, _number.rangeEach)(range.from, range.to, function (index) {
	        var value = void 0;
	
	        if (type === 'row') {
	          value = _this2.dataFactory(specifierValue, index);
	        } else if (type === 'col') {
	          value = _this2.dataFactory(index, specifierValue);
	        } else {
	          throw new Error('Unsupported sample type');
	        }
	
	        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 (!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) {
	            var computedKey = type === 'row' ? 'col' : 'row';
	
	            sample.strings.push(_defineProperty({ value: value }, computedKey, index));
	            sampledValues.push(value);
	            sample.needed--;
	          }
	        }
	      });
	
	      return samples;
	    }
	  }]);
	
	  return SamplesGenerator;
	}();
	
	exports.default = SamplesGenerator;
	
	/***/ }),
	/* 176 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _array = __webpack_require__(2);
	
	var _object = __webpack_require__(1);
	
	var _number = __webpack_require__(6);
	
	var MIXIN_NAME = 'arrayMapper';
	
	/**
	 * @type {Object}
	 */
	var arrayMapper = {
	  _arrayMap: [],
	
	  /**
	   * Get value by map index.
	   *
	   * @param {Number} index Array index.
	   * @return {*} Returns value mapped to passed index.
	   */
	  getValueByIndex: function getValueByIndex(index) {
	    var value = void 0;
	
	    // eslint-disable-next-line no-cond-assign, no-return-assign
	    return (value = this._arrayMap[index]) === void 0 ? null : value;
	  },
	
	
	  /**
	   * Get map index by its value.
	   *
	   * @param {*} value Value to search.
	   * @returns {Number} Returns array index.
	   */
	  getIndexByValue: function getIndexByValue(value) {
	    var index = void 0;
	
	    // eslint-disable-next-line no-cond-assign, no-return-assign
	    return (index = this._arrayMap.indexOf(value)) === -1 ? null : index;
	  },
	
	
	  /**
	   * Insert new items to array mapper starting at passed index. New entries will be a continuation of last value in the array.
	   *
	   * @param {Number} index Array index.
	   * @param {Number} [amount=1] Defines how many items will be created to an array.
	   * @returns {Array} Returns added items.
	   */
	  insertItems: function insertItems(index) {
	    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(index + count, 0, newIndex + count));
	    });
	
	    return addedItems;
	  },
	
	
	  /**
	   * Remove items from array mapper.
	   *
	   * @param {Number} index Array index.
	   * @param {Number} [amount=1] Defines how many items will be created to an array.
	   * @returns {Array} Returns removed items.
	   */
	  removeItems: function removeItems(index) {
	    var _this2 = this;
	
	    var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
	
	    var removedItems = [];
	
	    if (Array.isArray(index)) {
	      var mapCopy = [].concat(this._arrayMap);
	
	      // Sort descending
	      index.sort(function (a, b) {
	        return b - a;
	      });
	
	      removedItems = (0, _array.arrayReduce)(index, function (acc, item) {
	        _this2._arrayMap.splice(item, 1);
	
	        return acc.concat(mapCopy.slice(item, item + 1));
	      }, []);
	    } else {
	      removedItems = this._arrayMap.splice(index, amount);
	    }
	
	    return removedItems;
	  },
	
	
	  /**
	   * Unshift items (remove and shift chunk of array to the left).
	   *
	   * @param {Number|Array} index 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(index) {
	    var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
	
	    var removedItems = this.removeItems(index, amount);
	
	    function countRowShift(logicalRow) {
	      // Todo: compare perf between reduce vs sort->each->brake
	      return (0, _array.arrayReduce)(removedItems, function (count, removedLogicalRow) {
	        if (logicalRow > removedLogicalRow) {
	          count++;
	        }
	
	        return count;
	      }, 0);
	    }
	
	    this._arrayMap = (0, _array.arrayMap)(this._arrayMap, function (logicalRow, physicalRow) {
	      var rowShift = countRowShift(logicalRow);
	
	      if (rowShift) {
	        logicalRow -= rowShift;
	      }
	
	      return logicalRow;
	    });
	  },
	
	
	  /**
	   * Shift (right shifting) items starting at passed index.
	   *
	   * @param {Number} index Array index.
	   * @param {Number} [amount=1] Defines how many items will be created to an array.
	   */
	  shiftItems: function shiftItems(index) {
	    var _this3 = this;
	
	    var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
	
	    this._arrayMap = (0, _array.arrayMap)(this._arrayMap, function (row) {
	      if (row >= index) {
	        row += amount;
	      }
	
	      return row;
	    });
	
	    (0, _number.rangeEach)(amount - 1, function (count) {
	      _this3._arrayMap.splice(index + count, 0, index + count);
	    });
	  },
	
	
	  /**
	   * 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
	});
	
	exports.default = arrayMapper;
	
	/***/ }),
	/* 177 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _number = __webpack_require__(6);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	var STATE_INITIALIZED = 0;
	var STATE_BUILT = 1;
	var STATE_APPENDED = 2;
	var UNIT = 'px';
	
	/**
	 * @class
	 * @private
	 */
	
	var BaseUI = function () {
	  function BaseUI(hotInstance) {
	    _classCallCheck(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.
	   */
	
	
	  _createClass(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 = document.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;
	}();
	
	exports.default = BaseUI;
	
	/***/ }),
	/* 178 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	var STATE_INITIALIZED = 0;
	var STATE_BUILT = 1;
	var STATE_APPENDED = 2;
	var UNIT = 'px';
	
	/**
	 * @class
	 * @private
	 */
	
	var BaseUI = function () {
	  function BaseUI(hotInstance) {
	    _classCallCheck(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.
	   */
	
	
	  _createClass(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 = document.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;
	}();
	
	exports.default = BaseUI;
	
	/***/ }),
	/* 179 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	/*!
	 * https://github.com/Starcounter-Jack/JSON-Patch
	 * json-patch-duplex.js version: 0.5.7
	 * (c) 2013 Joachim Wester
	 * MIT license
	 */
	var __extends = undefined && undefined.__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 (typeof a === 'undefined' ? 'undefined' : _typeof(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 (_typeof(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 ((typeof obj === 'undefined' ? 'undefined' : _typeof(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 (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 ((typeof oldVal === 'undefined' ? 'undefined' : _typeof(oldVal)) == "object" && oldVal != null && (typeof newVal === 'undefined' ? 'undefined' : _typeof(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" || (typeof obj === 'undefined' ? 'undefined' : _typeof(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 ((typeof operation === 'undefined' ? 'undefined' : _typeof(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;
	}
	
	/***/ }),
	/* 180 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	__webpack_require__(89);
	
	__webpack_require__(103);
	
	__webpack_require__(104);
	
	__webpack_require__(108);
	
	__webpack_require__(109);
	
	__webpack_require__(111);
	
	__webpack_require__(113);
	
	__webpack_require__(114);
	
	__webpack_require__(115);
	
	__webpack_require__(116);
	
	__webpack_require__(117);
	
	__webpack_require__(118);
	
	__webpack_require__(119);
	
	__webpack_require__(120);
	
	__webpack_require__(122);
	
	__webpack_require__(124);
	
	__webpack_require__(125);
	
	__webpack_require__(126);
	
	__webpack_require__(127);
	
	__webpack_require__(128);
	
	__webpack_require__(129);
	
	__webpack_require__(130);
	
	__webpack_require__(131);
	
	__webpack_require__(132);
	
	__webpack_require__(133);
	
	__webpack_require__(134);
	
	__webpack_require__(135);
	
	__webpack_require__(136);
	
	__webpack_require__(78);
	
	__webpack_require__(137);
	
	__webpack_require__(138);
	
	__webpack_require__(140);
	
	__webpack_require__(141);
	
	__webpack_require__(142);
	
	__webpack_require__(143);
	
	__webpack_require__(144);
	
	__webpack_require__(145);
	
	__webpack_require__(146);
	
	__webpack_require__(148);
	
	__webpack_require__(149);
	
	__webpack_require__(150);
	
	__webpack_require__(152);
	
	__webpack_require__(153);
	
	__webpack_require__(154);
	
	__webpack_require__(201);
	
	__webpack_require__(202);
	
	__webpack_require__(203);
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var _cellTypes = __webpack_require__(81);
	
	var _core = __webpack_require__(82);
	
	var _core2 = _interopRequireDefault(_core);
	
	var _jquery = __webpack_require__(246);
	
	var _jquery2 = _interopRequireDefault(_jquery);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _ghostTable = __webpack_require__(85);
	
	var _ghostTable2 = _interopRequireDefault(_ghostTable);
	
	var _array = __webpack_require__(2);
	
	var arrayHelpers = _interopRequireWildcard(_array);
	
	var _browser = __webpack_require__(26);
	
	var browserHelpers = _interopRequireWildcard(_browser);
	
	var _data = __webpack_require__(84);
	
	var dataHelpers = _interopRequireWildcard(_data);
	
	var _date = __webpack_require__(170);
	
	var dateHelpers = _interopRequireWildcard(_date);
	
	var _feature = __webpack_require__(34);
	
	var featureHelpers = _interopRequireWildcard(_feature);
	
	var _function = __webpack_require__(35);
	
	var functionHelpers = _interopRequireWildcard(_function);
	
	var _mixed = __webpack_require__(22);
	
	var mixedHelpers = _interopRequireWildcard(_mixed);
	
	var _number = __webpack_require__(6);
	
	var numberHelpers = _interopRequireWildcard(_number);
	
	var _object = __webpack_require__(1);
	
	var objectHelpers = _interopRequireWildcard(_object);
	
	var _setting = __webpack_require__(83);
	
	var settingHelpers = _interopRequireWildcard(_setting);
	
	var _string = __webpack_require__(32);
	
	var stringHelpers = _interopRequireWildcard(_string);
	
	var _unicode = __webpack_require__(18);
	
	var unicodeHelpers = _interopRequireWildcard(_unicode);
	
	var _element = __webpack_require__(0);
	
	var domHelpers = _interopRequireWildcard(_element);
	
	var _event = __webpack_require__(10);
	
	var domEventHelpers = _interopRequireWildcard(_event);
	
	var _index = __webpack_require__(247);
	
	var plugins = _interopRequireWildcard(_index);
	
	var _plugins = __webpack_require__(5);
	
	var _defaultSettings = __webpack_require__(174);
	
	var _defaultSettings2 = _interopRequireDefault(_defaultSettings);
	
	var _rootInstance = __webpack_require__(173);
	
	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; } }
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function Handsontable(rootElement, userSettings) {
	  var instance = new _core2.default(rootElement, userSettings || {}, _rootInstance.rootInstanceSymbol);
	
	  instance.init();
	
	  return instance;
	}
	
	(0, _jquery2.default)(Handsontable);
	
	Handsontable.Core = _core2.default;
	Handsontable.DefaultSettings = _defaultSettings2.default;
	Handsontable.EventManager = _eventManager2.default;
	Handsontable._getListenersCounter = _eventManager.getListenersCounter; // For MemoryLeak tests
	
	Handsontable.buildDate = '12/10/2017 10:04:29';
	Handsontable.packageName = 'handsontable';
	Handsontable.version = '0.34.5';
	
	var baseVersion = '';
	
	if (baseVersion) {
	  Handsontable.baseVersion = baseVersion;
	}
	
	// Export Hooks singleton
	Handsontable.hooks = _pluginHooks2.default.getSingleton();
	
	// TODO: Remove this exports after rewrite tests about this module
	Handsontable.__GhostTable = _ghostTable2.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[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[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[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[pluginName + 'Plugin'] = plugin;
	  } else {
	    Handsontable.plugins[pluginName] = plugin;
	  }
	});
	
	Handsontable.plugins.registerPlugin = _plugins.registerPlugin;
	
	exports.default = Handsontable;
	
	/***/ }),
	/* 181 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var dP = __webpack_require__(17);
	var anObject = __webpack_require__(16);
	var getKeys = __webpack_require__(36);
	
	module.exports = __webpack_require__(20) ? Object.defineProperties : function defineProperties(O, Properties) {
	  anObject(O);
	  var keys = getKeys(Properties);
	  var length = keys.length;
	  var i = 0;
	  var P;
	  while (length > i) dP.f(O, P = keys[i++], Properties[P]);
	  return O;
	};
	
	
	/***/ }),
	/* 182 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	var create = __webpack_require__(66);
	var descriptor = __webpack_require__(43);
	var setToStringTag = __webpack_require__(46);
	var IteratorPrototype = {};
	
	// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
	__webpack_require__(29)(IteratorPrototype, __webpack_require__(9)('iterator'), function () { return this; });
	
	module.exports = function (Constructor, NAME, next) {
	  Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });
	  setToStringTag(Constructor, NAME + ' Iterator');
	};
	
	
	/***/ }),
	/* 183 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
	var has = __webpack_require__(24);
	var toObject = __webpack_require__(38);
	var IE_PROTO = __webpack_require__(68)('IE_PROTO');
	var ObjectProto = Object.prototype;
	
	module.exports = 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 ? ObjectProto : null;
	};
	
	
	/***/ }),
	/* 184 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var isObject = __webpack_require__(14);
	var setPrototypeOf = __webpack_require__(102).set;
	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;
	};
	
	
	/***/ }),
	/* 185 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
	var speciesConstructor = __webpack_require__(186);
	
	module.exports = function (original, length) {
	  return new (speciesConstructor(original))(length);
	};
	
	
	/***/ }),
	/* 186 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var isObject = __webpack_require__(14);
	var isArray = __webpack_require__(105);
	var SPECIES = __webpack_require__(9)('species');
	
	module.exports = function (original) {
	  var C;
	  if (isArray(original)) {
	    C = original.constructor;
	    // cross-realm fallback
	    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
	    if (isObject(C)) {
	      C = C[SPECIES];
	      if (C === null) C = undefined;
	    }
	  } return C === undefined ? Array : C;
	};
	
	
	/***/ }),
	/* 187 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// 7.3.20 SpeciesConstructor(O, defaultConstructor)
	var anObject = __webpack_require__(16);
	var aFunction = __webpack_require__(55);
	var SPECIES = __webpack_require__(9)('species');
	module.exports = function (O, D) {
	  var C = anObject(O).constructor;
	  var S;
	  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
	};
	
	
	/***/ }),
	/* 188 */
	/***/ (function(module, exports) {
	
	// fast apply, http://jsperf.lnkit.com/fast-apply/5
	module.exports = function (fn, args, that) {
	  var un = that === undefined;
	  switch (args.length) {
	    case 0: return un ? fn()
	                      : fn.call(that);
	    case 1: return un ? fn(args[0])
	                      : fn.call(that, args[0]);
	    case 2: return un ? fn(args[0], args[1])
	                      : fn.call(that, args[0], args[1]);
	    case 3: return un ? fn(args[0], args[1], args[2])
	                      : fn.call(that, args[0], args[1], args[2]);
	    case 4: return un ? fn(args[0], args[1], args[2], args[3])
	                      : fn.call(that, args[0], args[1], args[2], args[3]);
	  } return fn.apply(that, args);
	};
	
	
	/***/ }),
	/* 189 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var global = __webpack_require__(11);
	var macrotask = __webpack_require__(73).set;
	var Observer = global.MutationObserver || global.WebKitMutationObserver;
	var process = global.process;
	var Promise = global.Promise;
	var isNode = __webpack_require__(37)(process) == 'process';
	
	module.exports = function () {
	  var head, last, notify;
	
	  var flush = function () {
	    var parent, fn;
	    if (isNode && (parent = process.domain)) parent.exit();
	    while (head) {
	      fn = head.fn;
	      head = head.next;
	      try {
	        fn();
	      } catch (e) {
	        if (head) notify();
	        else last = undefined;
	        throw e;
	      }
	    } last = undefined;
	    if (parent) parent.enter();
	  };
	
	  // Node.js
	  if (isNode) {
	    notify = function () {
	      process.nextTick(flush);
	    };
	  // browsers with MutationObserver
	  } else if (Observer) {
	    var toggle = true;
	    var node = document.createTextNode('');
	    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
	    notify = function () {
	      node.data = toggle = !toggle;
	    };
	  // environments with maybe non-completely correct, but existent Promise
	  } else if (Promise && Promise.resolve) {
	    var promise = Promise.resolve();
	    notify = function () {
	      promise.then(flush);
	    };
	  // for other environments - macrotask based on:
	  // - setImmediate
	  // - MessageChannel
	  // - window.postMessag
	  // - onreadystatechange
	  // - setTimeout
	  } else {
	    notify = function () {
	      // strange IE + webpack dev server bug - use .call(global)
	      macrotask.call(global, flush);
	    };
	  }
	
	  return function (fn) {
	    var task = { fn: fn, next: undefined };
	    if (last) last.next = task;
	    if (!head) {
	      head = task;
	      notify();
	    } last = task;
	  };
	};
	
	
	/***/ }),
	/* 190 */
	/***/ (function(module, exports) {
	
	module.exports = function (exec) {
	  try {
	    return { e: false, v: exec() };
	  } catch (e) {
	    return { e: true, v: e };
	  }
	};
	
	
	/***/ }),
	/* 191 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var anObject = __webpack_require__(16);
	var isObject = __webpack_require__(14);
	var newPromiseCapability = __webpack_require__(110);
	
	module.exports = function (C, x) {
	  anObject(C);
	  if (isObject(x) && x.constructor === C) return x;
	  var promiseCapability = newPromiseCapability.f(C);
	  var resolve = promiseCapability.resolve;
	  resolve(x);
	  return promiseCapability.promise;
	};
	
	
	/***/ }),
	/* 192 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var global = __webpack_require__(11);
	var core = __webpack_require__(44);
	var LIBRARY = __webpack_require__(58);
	var wksExt = __webpack_require__(112);
	var defineProperty = __webpack_require__(17).f;
	module.exports = function (name) {
	  var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});
	  if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) });
	};
	
	
	/***/ }),
	/* 193 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// all enumerable object keys, includes symbols
	var getKeys = __webpack_require__(36);
	var gOPS = __webpack_require__(61);
	var pIE = __webpack_require__(48);
	module.exports = function (it) {
	  var result = getKeys(it);
	  var getSymbols = gOPS.f;
	  if (getSymbols) {
	    var symbols = getSymbols(it);
	    var isEnum = pIE.f;
	    var i = 0;
	    var key;
	    while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key);
	  } return result;
	};
	
	
	/***/ }),
	/* 194 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
	var toIObject = __webpack_require__(25);
	var gOPN = __webpack_require__(74).f;
	var toString = {}.toString;
	
	var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
	  ? Object.getOwnPropertyNames(window) : [];
	
	var getWindowNames = function (it) {
	  try {
	    return gOPN(it);
	  } catch (e) {
	    return windowNames.slice();
	  }
	};
	
	module.exports.f = function getOwnPropertyNames(it) {
	  return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));
	};
	
	
	/***/ }),
	/* 195 */
	/***/ (function(module, exports) {
	
	// 7.2.9 SameValue(x, y)
	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;
	};
	
	
	/***/ }),
	/* 196 */
	/***/ (function(module, exports, __webpack_require__) {
	
	var toInteger = __webpack_require__(52);
	var defined = __webpack_require__(33);
	// true  -> String#at
	// false -> String#codePointAt
	module.exports = function (TO_STRING) {
	  return function (that, pos) {
	    var s = String(defined(that));
	    var i = toInteger(pos);
	    var l = s.length;
	    var a, b;
	    if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
	    a = s.charCodeAt(i);
	    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
	      ? TO_STRING ? s.charAt(i) : a
	      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
	  };
	};
	
	
	/***/ }),
	/* 197 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	// 21.2.5.3 get RegExp.prototype.flags
	var anObject = __webpack_require__(16);
	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;
	};
	
	
	/***/ }),
	/* 198 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
	
	var toObject = __webpack_require__(38);
	var toAbsoluteIndex = __webpack_require__(53);
	var toLength = __webpack_require__(21);
	
	module.exports = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {
	  var O = toObject(this);
	  var len = toLength(O.length);
	  var to = toAbsoluteIndex(target, len);
	  var from = toAbsoluteIndex(start, len);
	  var end = arguments.length > 2 ? arguments[2] : undefined;
	  var count = Math.min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);
	  var inc = 1;
	  if (from < to && to < from + count) {
	    inc = -1;
	    from += count - 1;
	    to += count - 1;
	  }
	  while (count-- > 0) {
	    if (from in O) O[to] = O[from];
	    else delete O[to];
	    to += inc;
	    from += inc;
	  } return O;
	};
	
	
	/***/ }),
	/* 199 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
	
	var toObject = __webpack_require__(38);
	var toAbsoluteIndex = __webpack_require__(53);
	var toLength = __webpack_require__(21);
	module.exports = function fill(value /* , start = 0, end = @length */) {
	  var O = toObject(this);
	  var length = toLength(O.length);
	  var aLen = arguments.length;
	  var index = toAbsoluteIndex(aLen > 1 ? arguments[1] : undefined, length);
	  var end = aLen > 2 ? arguments[2] : undefined;
	  var endPos = end === undefined ? length : toAbsoluteIndex(end, length);
	  while (endPos > index) O[index++] = value;
	  return O;
	};
	
	
	/***/ }),
	/* 200 */
	/***/ (function(module, exports, __webpack_require__) {
	
	// all object keys, includes non-enumerable and symbols
	var gOPN = __webpack_require__(74);
	var gOPS = __webpack_require__(61);
	var anObject = __webpack_require__(16);
	var Reflect = __webpack_require__(11).Reflect;
	module.exports = Reflect && Reflect.ownKeys || function ownKeys(it) {
	  var keys = gOPN.f(anObject(it));
	  var getSymbols = gOPS.f;
	  return getSymbols ? keys.concat(getSymbols(it)) : keys;
	};
	
	
	/***/ }),
	/* 201 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 202 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 203 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 204 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	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; }
	
	/**
	 * 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 = function (_Overlay) {
	  _inherits(DebugOverlay, _Overlay);
	
	  /**
	   * @param {Walkontable} wotInstance
	   */
	  function DebugOverlay(wotInstance) {
	    _classCallCheck(this, DebugOverlay);
	
	    var _this = _possibleConstructorReturn(this, (DebugOverlay.__proto__ || Object.getPrototypeOf(DebugOverlay)).call(this, wotInstance));
	
	    _this.clone = _this.makeClone(_base2.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;
	}(_base2.default);
	
	_base2.default.registerOverlay(_base2.default.CLONE_DEBUG, DebugOverlay);
	
	exports.default = DebugOverlay;
	
	/***/ }),
	/* 205 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.toSingleLine = toSingleLine;
	
	var _array = __webpack_require__(2);
	
	/**
	 * 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 = 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();
	} /* eslint-disable import/prefer-default-export */
	
	/***/ }),
	/* 206 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	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 LeftOverlay
	 */
	var LeftOverlay = function (_Overlay) {
	  _inherits(LeftOverlay, _Overlay);
	
	  /**
	   * @param {Walkontable} wotInstance
	   */
	  function LeftOverlay(wotInstance) {
	    _classCallCheck(this, LeftOverlay);
	
	    var _this = _possibleConstructorReturn(this, (LeftOverlay.__proto__ || Object.getPrototypeOf(LeftOverlay)).call(this, wotInstance));
	
	    _this.clone = _this.makeClone(_base2.default.CLONE_LEFT);
	    return _this;
	  }
	
	  /**
	   * Checks if overlay should be fully rendered
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(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() {
	      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 === window && (!preventOverflow || preventOverflow !== 'horizontal')) {
	        var box = this.wot.wtTable.hider.getBoundingClientRect();
	        var left = Math.ceil(box.left);
	        var right = Math.ceil(box.right);
	        var finalLeft = void 0;
	        var finalTop = void 0;
	
	        finalTop = this.wot.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
	     */
	
	  }, {
	    key: 'setScrollPosition',
	    value: function setScrollPosition(pos) {
	      if (this.mainTableScrollableElement === window) {
	        window.scrollTo(pos, (0, _element.getWindowScrollTop)());
	      } else {
	        this.mainTableScrollableElement.scrollLeft = pos;
	      }
	    }
	
	    /**
	     * 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 sum = 0;
	      var defaultColumnWidth = this.wot.wtSettings.defaultColumnWidth;
	
	      while (from < to) {
	        sum += this.wot.wtTable.getStretchedColumnWidth(from) || defaultColumnWidth;
	        from++;
	      }
	
	      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 masterHolder = this.wot.wtTable.holder;
	      var scrollbarHeight = masterHolder.clientHeight === masterHolder.offsetHeight ? 0 : (0, _element.getScrollbarWidth)();
	      var overlayRoot = this.clone.wtTable.holder.parentNode;
	      var overlayRootStyle = overlayRoot.style;
	      var preventOverflow = this.wot.getSetting('preventOverflow');
	      var tableWidth = void 0;
	
	      if (this.trimmingContainer !== window || preventOverflow === 'vertical') {
	        var height = this.wot.wtViewport.getWorkspaceHeight() - scrollbarHeight;
	
	        height = Math.min(height, (0, _element.innerHeight)(this.wot.wtTable.wtRootElement));
	
	        overlayRootStyle.height = height + 'px';
	      } else {
	        overlayRootStyle.height = '';
	      }
	
	      this.clone.wtTable.holder.style.height = overlayRootStyle.height;
	
	      tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE);
	      overlayRootStyle.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px';
	    }
	
	    /**
	     * Adjust overlay root childs size
	     */
	
	  }, {
	    key: 'adjustRootChildrenSize',
	    value: function adjustRootChildrenSize() {
	      var scrollbarWidth = (0, _element.getScrollbarWidth)();
	
	      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 = 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 = 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 = 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 sourceCol {Number} Column index which you want to scroll to
	     * @param [beyondRendered=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default)
	     */
	
	  }, {
	    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)();
	      }
	      if (beyondRendered) {
	        newX += this.sumCellSizes(0, sourceCol + 1);
	        newX -= this.wot.wtViewport.getViewportWidth();
	      } else {
	        newX += this.sumCellSizes(this.wot.getSetting('fixedColumnsLeft'), sourceCol);
	      }
	      newX += scrollbarCompensation;
	
	      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 === window) {
	        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);
	    }
	
	    /**
	     * 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;
	}(_base2.default);
	
	_base2.default.registerOverlay(_base2.default.CLONE_LEFT, LeftOverlay);
	
	exports.default = LeftOverlay;
	
	/***/ }),
	/* 207 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	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 TopOverlay
	 */
	var TopOverlay = function (_Overlay) {
	  _inherits(TopOverlay, _Overlay);
	
	  /**
	   * @param {Walkontable} wotInstance
	   */
	  function TopOverlay(wotInstance) {
	    _classCallCheck(this, TopOverlay);
	
	    var _this = _possibleConstructorReturn(this, (TopOverlay.__proto__ || Object.getPrototypeOf(TopOverlay)).call(this, wotInstance));
	
	    _this.clone = _this.makeClone(_base2.default.CLONE_TOP);
	    return _this;
	  }
	
	  /**
	   * Checks if overlay should be fully rendered
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(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 === window && (!preventOverflow || preventOverflow !== 'vertical')) {
	        var box = this.wot.wtTable.hider.getBoundingClientRect();
	        var top = Math.ceil(box.top);
	        var bottom = Math.ceil(box.bottom);
	        var finalLeft = void 0;
	        var finalTop = void 0;
	
	        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
	     */
	
	  }, {
	    key: 'setScrollPosition',
	    value: function setScrollPosition(pos) {
	      if (this.mainTableScrollableElement === window) {
	        window.scrollTo((0, _element.getWindowScrollLeft)(), pos);
	      } else {
	        this.mainTableScrollableElement.scrollTop = pos;
	      }
	    }
	
	    /**
	     * 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 sum = 0;
	      var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight;
	
	      while (from < to) {
	        var height = this.wot.wtTable.getRowHeight(from);
	
	        sum += height === void 0 ? defaultRowHeight : height;
	        from++;
	      }
	
	      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 masterHolder = this.wot.wtTable.holder;
	      var scrollbarWidth = masterHolder.clientWidth === masterHolder.offsetWidth ? 0 : (0, _element.getScrollbarWidth)();
	      var overlayRoot = this.clone.wtTable.holder.parentNode;
	      var overlayRootStyle = overlayRoot.style;
	      var preventOverflow = this.wot.getSetting('preventOverflow');
	      var tableHeight = void 0;
	
	      if (this.trimmingContainer !== window || preventOverflow === 'horizontal') {
	        var width = this.wot.wtViewport.getWorkspaceWidth() - scrollbarWidth;
	
	        width = Math.min(width, (0, _element.innerWidth)(this.wot.wtTable.wtRootElement));
	
	        overlayRootStyle.width = width + 'px';
	      } else {
	        overlayRootStyle.width = '';
	      }
	
	      this.clone.wtTable.holder.style.width = overlayRootStyle.width;
	
	      tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE);
	      overlayRootStyle.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px';
	    }
	
	    /**
	     * Adjust overlay root childs size
	     */
	
	  }, {
	    key: 'adjustRootChildrenSize',
	    value: function adjustRootChildrenSize() {
	      var scrollbarWidth = (0, _element.getScrollbarWidth)();
	
	      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 = 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 = 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 = 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)();
	      }
	
	      if (bottomEdge) {
	        var fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
	        var fixedRowsTop = this.wot.getSetting('fixedRowsTop');
	        var totalRows = this.wot.getSetting('totalRows');
	
	        newY += this.sumCellSizes(0, sourceRow + 1);
	        newY -= this.wot.wtViewport.getViewportHeight() - this.sumCellSizes(totalRows - fixedRowsBottom, totalRows);
	        // Fix 1 pixel offset when cell is selected
	        newY += 1;
	      } else {
	        newY += this.sumCellSizes(this.wot.getSetting('fixedRowsTop'), sourceRow);
	      }
	      newY += scrollbarCompensation;
	
	      this.setScrollPosition(newY);
	    }
	
	    /**
	     * Gets table parent top position
	     *
	     * @returns {Number}
	     */
	
	  }, {
	    key: 'getTableParentOffset',
	    value: function getTableParentOffset() {
	      if (this.mainTableScrollableElement === window) {
	        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);
	    }
	
	    /**
	     * 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);
	
	        if (border) {
	          var corners = selection.getCorners();
	          border.disappear();
	          border.appear(corners);
	        }
	      }
	    }
	
	    /**
	     * Redrawing borders of all selections
	     */
	
	  }, {
	    key: 'redrawAllSelectionsBorders',
	    value: function redrawAllSelectionsBorders() {
	      var selections = this.wot.selections;
	
	      this.redrawSelectionBorders(selections.current);
	      this.redrawSelectionBorders(selections.area);
	      this.redrawSelectionBorders(selections.fill);
	      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;
	}(_base2.default);
	
	_base2.default.registerOverlay(_base2.default.CLONE_TOP, TopOverlay);
	
	exports.default = TopOverlay;
	
	/***/ }),
	/* 208 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _base = __webpack_require__(31);
	
	var _base2 = _interopRequireDefault(_base);
	
	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 TopLeftCornerOverlay
	 */
	var TopLeftCornerOverlay = function (_Overlay) {
	  _inherits(TopLeftCornerOverlay, _Overlay);
	
	  /**
	   * @param {Walkontable} wotInstance
	   */
	  function TopLeftCornerOverlay(wotInstance) {
	    _classCallCheck(this, TopLeftCornerOverlay);
	
	    var _this = _possibleConstructorReturn(this, (TopLeftCornerOverlay.__proto__ || Object.getPrototypeOf(TopLeftCornerOverlay)).call(this, wotInstance));
	
	    _this.clone = _this.makeClone(_base2.default.CLONE_TOP_LEFT_CORNER);
	    return _this;
	  }
	
	  /**
	   * Checks if overlay should be fully rendered
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(TopLeftCornerOverlay, [{
	    key: 'shouldBeRendered',
	    value: function shouldBeRendered() {
	      return !!((this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length) && (this.wot.getSetting('fixedColumnsLeft') || this.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 === window) {
	        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 = -left + 'px';
	          }
	        }
	
	        if (!preventOverflow || preventOverflow === 'horizontal') {
	          if (top < 0 && bottom - overlayRoot.offsetHeight > 0) {
	            finalTop = -top + 'px';
	          }
	        }
	        (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop);
	      } else {
	        (0, _element.resetCssTransform)(overlayRoot);
	      }
	      overlayRoot.style.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px';
	      overlayRoot.style.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px';
	    }
	  }]);
	
	  return TopLeftCornerOverlay;
	}(_base2.default);
	
	_base2.default.registerOverlay(_base2.default.CLONE_TOP_LEFT_CORNER, TopLeftCornerOverlay);
	
	exports.default = TopLeftCornerOverlay;
	
	/***/ }),
	/* 209 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _border2 = __webpack_require__(167);
	
	var _border3 = _interopRequireDefault(_border2);
	
	var _coords = __webpack_require__(49);
	
	var _coords2 = _interopRequireDefault(_coords);
	
	var _range = __webpack_require__(79);
	
	var _range2 = _interopRequireDefault(_range);
	
	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"); } }
	
	/**
	 * @class Selection
	 */
	var Selection = function () {
	  /**
	   * @param {Object} settings
	   * @param {CellRange} cellRange
	   */
	  function Selection(settings, cellRange) {
	    _classCallCheck(this, Selection);
	
	    this.settings = settings;
	    this.cellRange = cellRange || null;
	    this.instanceBorders = {};
	  }
	
	  /**
	   * 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}
	   */
	
	
	  _createClass(Selection, [{
	    key: 'getBorder',
	    value: function getBorder(wotInstance) {
	      if (this.instanceBorders[wotInstance.guid]) {
	        return this.instanceBorders[wotInstance.guid];
	      }
	
	      // where is this returned?
	      this.instanceBorders[wotInstance.guid] = new _border3.default(wotInstance, this.settings);
	    }
	
	    /**
	     * 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 _range2.default(coords, coords, coords);
	      } else {
	        this.cellRange.expand(coords);
	      }
	    }
	
	    /**
	     * 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
	     */
	
	  }, {
	    key: 'clear',
	    value: function clear() {
	      this.cellRange = null;
	    }
	
	    /**
	     * 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
	     */
	
	  }, {
	    key: 'addClassAtCoords',
	    value: function addClassAtCoords(wotInstance, sourceRow, sourceColumn, className) {
	      var TD = wotInstance.wtTable.getCell(new _coords2.default(sourceRow, sourceColumn));
	
	      if ((typeof TD === 'undefined' ? 'undefined' : _typeof(TD)) === 'object') {
	        (0, _element.addClass)(TD, className);
	      }
	    }
	
	    /**
	     * @param wotInstance
	     */
	
	  }, {
	    key: 'draw',
	    value: function draw(wotInstance) {
	      if (this.isEmpty()) {
	        if (this.settings.border) {
	          var border = this.getBorder(wotInstance);
	
	          if (border) {
	            border.disappear();
	          }
	        }
	
	        return;
	      }
	      var renderedRows = wotInstance.wtTable.getRenderedRowsCount();
	      var renderedColumns = wotInstance.wtTable.getRenderedColumnsCount();
	      var corners = this.getCorners();
	      var sourceRow = void 0,
	          sourceCol = void 0,
	          TH = void 0;
	
	      for (var column = 0; column < renderedColumns; column++) {
	        sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(column);
	
	        if (sourceCol >= corners[1] && sourceCol <= corners[3]) {
	          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++) {
	        sourceRow = wotInstance.wtTable.rowFilter.renderedToSource(row);
	
	        if (sourceRow >= corners[0] && sourceRow <= corners[2]) {
	          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++) {
	          sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(_column);
	
	          if (sourceRow >= corners[0] && sourceRow <= corners[2] && sourceCol >= corners[1] && sourceCol <= corners[3]) {
	            // selected cell
	            if (this.settings.className) {
	              this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.className);
	            }
	          } else if (sourceRow >= corners[0] && sourceRow <= corners[2]) {
	            // selection is in this row
	            if (this.settings.highlightRowClassName) {
	              this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightRowClassName);
	            }
	          } else if (sourceCol >= corners[1] && sourceCol <= corners[3]) {
	            // selection is in this column
	            if (this.settings.highlightColumnClassName) {
	              this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightColumnClassName);
	            }
	          }
	        }
	      }
	      wotInstance.getSetting('onBeforeDrawBorders', corners, this.settings.className);
	
	      if (this.settings.border) {
	        var _border = this.getBorder(wotInstance);
	
	        if (_border) {
	          // warning! border.appear modifies corners!
	          _border.appear(corners);
	        }
	      }
	    }
	  }]);
	
	  return Selection;
	}();
	
	exports.default = Selection;
	
	/***/ }),
	/* 210 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	/**
	 * 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) {
	    if (element.attachEvent) {
	      element.attachEvent('on' + event, handler);
	    } else {
	      element.addEventListener(event, handler, false);
	    }
	  },
	      _unObserve = function _unObserve(element, event, handler) {
	    if (element.removeEventListener) {
	      element.removeEventListener(event, handler, false);
	    } else {
	      element.detachEvent('on' + event, handler);
	    }
	  },
	      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);
	    }
	
	    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);
	    },
	    resize: resize
	  };
	}
	
	if (true) {
	  module.exports = autoResize;
	}
	
	/***/ }),
	/* 211 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _baseEditor = __webpack_require__(41);
	
	var _baseEditor2 = _interopRequireDefault(_baseEditor);
	
	var _element = __webpack_require__(0);
	
	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; }
	
	/**
	 * @private
	 * @editor CheckboxEditor
	 * @class CheckboxEditor
	 */
	var CheckboxEditor = function (_BaseEditor) {
	  _inherits(CheckboxEditor, _BaseEditor);
	
	  function CheckboxEditor() {
	    _classCallCheck(this, CheckboxEditor);
	
	    return _possibleConstructorReturn(this, (CheckboxEditor.__proto__ || Object.getPrototypeOf(CheckboxEditor)).apply(this, arguments));
	  }
	
	  _createClass(CheckboxEditor, [{
	    key: 'beginEditing',
	    value: function beginEditing(initialValue, event) {
	      // editorManager return double click event as undefined
	      if (event === void 0) {
	        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;
	}(_baseEditor2.default);
	
	exports.default = CheckboxEditor;
	
	/***/ }),
	/* 212 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _moment = __webpack_require__(50);
	
	var _moment2 = _interopRequireDefault(_moment);
	
	var _pikaday = __webpack_require__(213);
	
	var _pikaday2 = _interopRequireDefault(_pikaday);
	
	__webpack_require__(214);
	
	var _element = __webpack_require__(0);
	
	var _object = __webpack_require__(1);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _unicode = __webpack_require__(18);
	
	var _event = __webpack_require__(10);
	
	var _textEditor = __webpack_require__(51);
	
	var _textEditor2 = _interopRequireDefault(_textEditor);
	
	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; }
	
	/**
	 * @private
	 * @editor DateEditor
	 * @class DateEditor
	 * @dependencies TextEditor moment pikaday
	 */
	var DateEditor = function (_TextEditor) {
	  _inherits(DateEditor, _TextEditor);
	
	  /**
	   * @param {Core} hotInstance Handsontable instance
	   * @private
	   */
	  function DateEditor(hotInstance) {
	    _classCallCheck(this, DateEditor);
	
	    // TODO: Move this option to general settings
	    var _this = _possibleConstructorReturn(this, (DateEditor.__proto__ || Object.getPrototypeOf(DateEditor)).call(this, hotInstance));
	
	    _this.defaultDateFormat = 'DD/MM/YYYY';
	    _this.isCellEdited = false;
	    _this.parentDestroyed = false;
	    return _this;
	  }
	
	  _createClass(DateEditor, [{
	    key: 'init',
	    value: function init() {
	      var _this2 = this;
	
	      if (typeof _moment2.default !== 'function') {
	        throw new Error('You need to include moment.js to your project.');
	      }
	
	      if (typeof _pikaday2.default !== 'function') {
	        throw new Error('You need to include Pikaday to your project.');
	      }
	      _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(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() {
	      _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'createElements', this).call(this);
	
	      this.datePicker = document.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');
	      document.body.appendChild(this.datePicker);
	
	      this.$datePicker = new _pikaday2.default(this.getDatePickerConfig());
	      var eventManager = new _eventManager2.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) {
	      this._opened = false;
	      _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(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;
	
	      _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(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(setTimeout(function () {
	        _this3.instance.selection.refreshBorders();
	      }, 0));
	
	      _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(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();
	      _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(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 = void 0;
	      var isMouseDown = this.instance.view.isMouseDown();
	      var isMeta = event ? (0, _unicode.isMetaKey)(event.keyCode) : false;
	
	      this.datePickerStyle.top = window.pageYOffset + offset.top + (0, _element.outerHeight)(this.TD) + 'px';
	      this.datePickerStyle.left = window.pageXOffset + offset.left + 'px';
	
	      this.$datePicker._onInputFocus = function () {};
	      datePickerConfig.format = dateFormat;
	
	      if (this.originalValue) {
	        dateStr = this.originalValue;
	
	        if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) {
	          this.$datePicker.setMoment((0, _moment2.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, _moment2.default)(dateStr, dateFormat, true).isValid()) {
	          this.$datePicker.setMoment((0, _moment2.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 (dateStr) {
	        if (!isNaN(dateStr.getTime())) {
	          dateStr = (0, _moment2.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;
	}(_textEditor2.default);
	
	exports.default = DateEditor;
	
	/***/ }),
	/* 213 */
	/***/ (function(module, exports) {
	
	module.exports = __WEBPACK_EXTERNAL_MODULE_213__;
	
	/***/ }),
	/* 214 */
	/***/ (function(module, exports) {
	
	
	
	/***/ }),
	/* 215 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _autocompleteEditor = __webpack_require__(168);
	
	var _autocompleteEditor2 = _interopRequireDefault(_autocompleteEditor);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	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; }
	
	/**
	 * @private
	 * @editor DropdownEditor
	 * @class DropdownEditor
	 * @dependencies AutocompleteEditor
	 */
	var DropdownEditor = function (_AutocompleteEditor) {
	  _inherits(DropdownEditor, _AutocompleteEditor);
	
	  function DropdownEditor() {
	    _classCallCheck(this, DropdownEditor);
	
	    return _possibleConstructorReturn(this, (DropdownEditor.__proto__ || Object.getPrototypeOf(DropdownEditor)).apply(this, arguments));
	  }
	
	  _createClass(DropdownEditor, [{
	    key: 'prepare',
	    value: function prepare(row, col, prop, td, originalValue, cellProperties) {
	      _get(DropdownEditor.prototype.__proto__ || Object.getPrototypeOf(DropdownEditor.prototype), 'prepare', this).call(this, row, col, prop, td, originalValue, cellProperties);
	      this.cellProperties.filter = false;
	      this.cellProperties.strict = true;
	    }
	  }]);
	
	  return DropdownEditor;
	}(_autocompleteEditor2.default);
	
	_pluginHooks2.default.getSingleton().add('beforeValidate', function (value, row, col, source) {
	  var cellMeta = this.getCellMeta(row, this.propToCol(col));
	
	  if (cellMeta.editor === DropdownEditor) {
	    if (cellMeta.strict === void 0) {
	      cellMeta.filter = false;
	      cellMeta.strict = true;
	    }
	  }
	});
	
	exports.default = DropdownEditor;
	
	/***/ }),
	/* 216 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _unicode = __webpack_require__(18);
	
	var _event = __webpack_require__(10);
	
	var _element = __webpack_require__(0);
	
	var _baseEditor = __webpack_require__(41);
	
	var _baseEditor2 = _interopRequireDefault(_baseEditor);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var MobileTextEditor = _baseEditor2.default.prototype.extend();
	var domDimensionsCache = {};
	
	/**
	 * @private
	 * @editor MobileTextEditor
	 * @class MobileTextEditor
	 */
	var createControls = function createControls() {
	  this.controls = {};
	
	  this.controls.leftButton = document.createElement('DIV');
	  this.controls.leftButton.className = 'leftButton';
	  this.controls.rightButton = document.createElement('DIV');
	  this.controls.rightButton.className = 'rightButton';
	  this.controls.upButton = document.createElement('DIV');
	  this.controls.upButton.className = 'upButton';
	  this.controls.downButton = document.createElement('DIV');
	  this.controls.downButton.className = 'downButton';
	
	  for (var button in this.controls) {
	    if (Object.prototype.hasOwnProperty.call(this.controls, button)) {
	      this.positionControls.appendChild(this.controls[button]);
	    }
	  }
	};
	
	MobileTextEditor.prototype.valueChanged = function () {
	  return this.initValue != this.getValue();
	};
	
	MobileTextEditor.prototype.init = function () {
	  var that = this;
	  this.eventManager = new _eventManager2.default(this.instance);
	
	  this.createElements();
	  this.bindEvents();
	
	  this.instance.addHook('afterDestroy', function () {
	    that.destroy();
	  });
	};
	
	MobileTextEditor.prototype.getValue = function () {
	  return this.TEXTAREA.value;
	};
	
	MobileTextEditor.prototype.setValue = function (newValue) {
	  this.initValue = newValue;
	
	  this.TEXTAREA.value = newValue;
	};
	
	MobileTextEditor.prototype.createElements = function () {
	  this.editorContainer = document.createElement('DIV');
	  this.editorContainer.className = 'htMobileEditorContainer';
	
	  this.cellPointer = document.createElement('DIV');
	  this.cellPointer.className = 'cellPointer';
	
	  this.moveHandle = document.createElement('DIV');
	  this.moveHandle.className = 'moveHandle';
	
	  this.inputPane = document.createElement('DIV');
	  this.inputPane.className = 'inputs';
	
	  this.positionControls = document.createElement('DIV');
	  this.positionControls.className = 'positionControls';
	
	  this.TEXTAREA = document.createElement('TEXTAREA');
	  (0, _element.addClass)(this.TEXTAREA, 'handsontableInput');
	
	  this.inputPane.appendChild(this.TEXTAREA);
	
	  this.editorContainer.appendChild(this.cellPointer);
	  this.editorContainer.appendChild(this.moveHandle);
	  this.editorContainer.appendChild(this.inputPane);
	  this.editorContainer.appendChild(this.positionControls);
	
	  createControls.call(this);
	
	  document.body.appendChild(this.editorContainer);
	};
	
	MobileTextEditor.prototype.onBeforeKeyDown = function (event) {
	  var instance = this;
	  var that = instance.getActiveEditor();
	
	  if (event.target !== that.TEXTAREA || (0, _event.isImmediatePropagationStopped)(event)) {
	    return;
	  }
	
	  switch (event.keyCode) {
	    case _unicode.KEY_CODES.ENTER:
	      that.close();
	      event.preventDefault(); // don't add newline to field
	      break;
	    case _unicode.KEY_CODES.BACKSPACE:
	      (0, _event.stopImmediatePropagation)(event); // backspace, delete, home, end should only work locally when cell is edited (not in table context)
	      break;
	    default:
	      break;
	  }
	};
	
	MobileTextEditor.prototype.open = function () {
	  this.instance.addHook('beforeKeyDown', this.onBeforeKeyDown);
	
	  (0, _element.addClass)(this.editorContainer, 'active');
	  (0, _element.removeClass)(this.cellPointer, 'hidden');
	
	  this.updateEditorPosition();
	};
	
	MobileTextEditor.prototype.focus = function () {
	  this.TEXTAREA.focus();
	  (0, _element.setCaretPosition)(this.TEXTAREA, this.TEXTAREA.value.length);
	};
	
	MobileTextEditor.prototype.close = function () {
	  this.TEXTAREA.blur();
	  this.instance.removeHook('beforeKeyDown', this.onBeforeKeyDown);
	
	  (0, _element.removeClass)(this.editorContainer, 'active');
	};
	
	MobileTextEditor.prototype.scrollToView = function () {
	  var coords = this.instance.getSelectedRange().highlight;
	  this.instance.view.scrollViewport(coords);
	};
	
	MobileTextEditor.prototype.hideCellPointer = function () {
	  if (!(0, _element.hasClass)(this.cellPointer, 'hidden')) {
	    (0, _element.addClass)(this.cellPointer, 'hidden');
	  }
	};
	
	MobileTextEditor.prototype.updateEditorPosition = function (x, y) {
	  if (x && y) {
	    x = parseInt(x, 10);
	    y = parseInt(y, 10);
	
	    this.editorContainer.style.top = y + 'px';
	    this.editorContainer.style.left = x + 'px';
	  } else {
	    var selection = this.instance.getSelected(),
	        selectedCell = this.instance.getCell(selection[0], selection[1]);
	
	    // cache sizes
	    if (!domDimensionsCache.cellPointer) {
	      domDimensionsCache.cellPointer = {
	        height: (0, _element.outerHeight)(this.cellPointer),
	        width: (0, _element.outerWidth)(this.cellPointer)
	      };
	    }
	    if (!domDimensionsCache.editorContainer) {
	      domDimensionsCache.editorContainer = {
	        width: (0, _element.outerWidth)(this.editorContainer)
	      };
	    }
	
	    if (selectedCell !== undefined) {
	      var scrollLeft = this.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollLeft)(this.instance.view.wt.wtOverlays.leftOverlay.holder);
	      var scrollTop = this.instance.view.wt.wtOverlays.topOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollTop)(this.instance.view.wt.wtOverlays.topOverlay.holder);
	
	      var selectedCellOffset = (0, _element.offset)(selectedCell),
	          selectedCellWidth = (0, _element.outerWidth)(selectedCell),
	          currentScrollPosition = {
	        x: scrollLeft,
	        y: scrollTop
	      };
	
	      this.editorContainer.style.top = parseInt(selectedCellOffset.top + (0, _element.outerHeight)(selectedCell) - currentScrollPosition.y + domDimensionsCache.cellPointer.height, 10) + 'px';
	      this.editorContainer.style.left = parseInt(window.innerWidth / 2 - domDimensionsCache.editorContainer.width / 2, 10) + 'px';
	
	      if (selectedCellOffset.left + selectedCellWidth / 2 > parseInt(this.editorContainer.style.left, 10) + domDimensionsCache.editorContainer.width) {
	        this.editorContainer.style.left = window.innerWidth - domDimensionsCache.editorContainer.width + 'px';
	      } else if (selectedCellOffset.left + selectedCellWidth / 2 < parseInt(this.editorContainer.style.left, 10) + 20) {
	        this.editorContainer.style.left = 0 + 'px';
	      }
	
	      this.cellPointer.style.left = parseInt(selectedCellOffset.left - domDimensionsCache.cellPointer.width / 2 - (0, _element.offset)(this.editorContainer).left + selectedCellWidth / 2 - currentScrollPosition.x, 10) + 'px';
	    }
	  }
	};
	
	MobileTextEditor.prototype.updateEditorData = function () {
	  var selected = this.instance.getSelected(),
	      selectedValue = this.instance.getDataAtCell(selected[0], selected[1]);
	
	  this.row = selected[0];
	  this.col = selected[1];
	  this.setValue(selectedValue);
	  this.updateEditorPosition();
	};
	
	MobileTextEditor.prototype.prepareAndSave = function () {
	  var val;
	
	  if (!this.valueChanged()) {
	    return;
	  }
	
	  if (this.instance.getSettings().trimWhitespace) {
	    val = [[String.prototype.trim.call(this.getValue())]];
	  } else {
	    val = [[this.getValue()]];
	  }
	
	  this.saveValue(val);
	};
	
	MobileTextEditor.prototype.bindEvents = function () {
	  var that = this;
	
	  this.eventManager.addEventListener(this.controls.leftButton, 'touchend', function (event) {
	    that.prepareAndSave();
	    that.instance.selection.transformStart(0, -1, null, true);
	    that.updateEditorData();
	    event.preventDefault();
	  });
	  this.eventManager.addEventListener(this.controls.rightButton, 'touchend', function (event) {
	    that.prepareAndSave();
	    that.instance.selection.transformStart(0, 1, null, true);
	    that.updateEditorData();
	    event.preventDefault();
	  });
	  this.eventManager.addEventListener(this.controls.upButton, 'touchend', function (event) {
	    that.prepareAndSave();
	    that.instance.selection.transformStart(-1, 0, null, true);
	    that.updateEditorData();
	    event.preventDefault();
	  });
	  this.eventManager.addEventListener(this.controls.downButton, 'touchend', function (event) {
	    that.prepareAndSave();
	    that.instance.selection.transformStart(1, 0, null, true);
	    that.updateEditorData();
	    event.preventDefault();
	  });
	
	  this.eventManager.addEventListener(this.moveHandle, 'touchstart', function (event) {
	    if (event.touches.length == 1) {
	      var touch = event.touches[0];
	      var onTouchPosition = {
	        x: that.editorContainer.offsetLeft,
	        y: that.editorContainer.offsetTop
	      };
	      var onTouchOffset = {
	        x: touch.pageX - onTouchPosition.x,
	        y: touch.pageY - onTouchPosition.y
	      };
	
	      that.eventManager.addEventListener(this, 'touchmove', function (event) {
	        var touch = event.touches[0];
	        that.updateEditorPosition(touch.pageX - onTouchOffset.x, touch.pageY - onTouchOffset.y);
	        that.hideCellPointer();
	        event.preventDefault();
	      });
	    }
	  });
	
	  this.eventManager.addEventListener(document.body, 'touchend', function (event) {
	    if (!(0, _element.isChildOf)(event.target, that.editorContainer) && !(0, _element.isChildOf)(event.target, that.instance.rootElement)) {
	      that.close();
	    }
	  });
	
	  this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.leftOverlay.holder, 'scroll', function (event) {
	    if (that.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer != window) {
	      that.hideCellPointer();
	    }
	  });
	
	  this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.topOverlay.holder, 'scroll', function (event) {
	    if (that.instance.view.wt.wtOverlays.topOverlay.trimmingContainer != window) {
	      that.hideCellPointer();
	    }
	  });
	};
	
	MobileTextEditor.prototype.destroy = function () {
	  this.eventManager.clear();
	
	  this.editorContainer.parentNode.removeChild(this.editorContainer);
	};
	
	exports.default = MobileTextEditor;
	
	/***/ }),
	/* 217 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _numbro = __webpack_require__(80);
	
	var _numbro2 = _interopRequireDefault(_numbro);
	
	var _textEditor = __webpack_require__(51);
	
	var _textEditor2 = _interopRequireDefault(_textEditor);
	
	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; }
	
	/**
	 * @private
	 * @editor NumericEditor
	 * @class NumericEditor
	 * @dependencies TextEditor numbro
	 */
	var NumericEditor = function (_TextEditor) {
	  _inherits(NumericEditor, _TextEditor);
	
	  function NumericEditor() {
	    _classCallCheck(this, NumericEditor);
	
	    return _possibleConstructorReturn(this, (NumericEditor.__proto__ || Object.getPrototypeOf(NumericEditor)).apply(this, arguments));
	  }
	
	  _createClass(NumericEditor, [{
	    key: 'beginEditing',
	
	    /**
	     * @param {*} initialValue
	     */
	    value: function beginEditing(initialValue) {
	      if (typeof initialValue === 'undefined' && this.originalValue) {
	        if (typeof this.cellProperties.language !== 'undefined') {
	          _numbro2.default.culture(this.cellProperties.language);
	        }
	        var decimalDelimiter = _numbro2.default.cultureData().delimiters.decimal;
	        initialValue = ('' + this.originalValue).replace('.', decimalDelimiter);
	      }
	      _get(NumericEditor.prototype.__proto__ || Object.getPrototypeOf(NumericEditor.prototype), 'beginEditing', this).call(this, initialValue);
	    }
	  }]);
	
	  return NumericEditor;
	}(_textEditor2.default);
	
	exports.default = NumericEditor;
	
	/***/ }),
	/* 218 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _element = __webpack_require__(0);
	
	var _textEditor = __webpack_require__(51);
	
	var _textEditor2 = _interopRequireDefault(_textEditor);
	
	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; }
	
	/**
	 * @private
	 * @editor PasswordEditor
	 * @class PasswordEditor
	 * @dependencies TextEditor
	 */
	var PasswordEditor = function (_TextEditor) {
	  _inherits(PasswordEditor, _TextEditor);
	
	  function PasswordEditor() {
	    _classCallCheck(this, PasswordEditor);
	
	    return _possibleConstructorReturn(this, (PasswordEditor.__proto__ || Object.getPrototypeOf(PasswordEditor)).apply(this, arguments));
	  }
	
	  _createClass(PasswordEditor, [{
	    key: 'createElements',
	    value: function createElements() {
	      _get(PasswordEditor.prototype.__proto__ || Object.getPrototypeOf(PasswordEditor.prototype), 'createElements', this).call(this);
	
	      this.TEXTAREA = document.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;
	}(_textEditor2.default);
	
	exports.default = PasswordEditor;
	
	/***/ }),
	/* 219 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _element = __webpack_require__(0);
	
	var _event = __webpack_require__(10);
	
	var _unicode = __webpack_require__(18);
	
	var _baseEditor = __webpack_require__(41);
	
	var _baseEditor2 = _interopRequireDefault(_baseEditor);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var SelectEditor = _baseEditor2.default.prototype.extend();
	
	/**
	 * @private
	 * @editor SelectEditor
	 * @class SelectEditor
	 */
	SelectEditor.prototype.init = function () {
	  this.select = document.createElement('SELECT');
	  (0, _element.addClass)(this.select, 'htSelectEditor');
	  this.select.style.display = 'none';
	  this.instance.rootElement.appendChild(this.select);
	  this.registerHooks();
	};
	
	SelectEditor.prototype.registerHooks = function () {
	  var _this = this;
	
	  this.instance.addHook('afterScrollHorizontally', function () {
	    return _this.refreshDimensions();
	  });
	  this.instance.addHook('afterScrollVertically', function () {
	    return _this.refreshDimensions();
	  });
	  this.instance.addHook('afterColumnResize', function () {
	    return _this.refreshDimensions();
	  });
	  this.instance.addHook('afterRowResize', function () {
	    return _this.refreshDimensions();
	  });
	};
	
	SelectEditor.prototype.prepare = function () {
	  _baseEditor2.default.prototype.prepare.apply(this, arguments);
	
	  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);
	
	  for (var option in options) {
	    if (Object.prototype.hasOwnProperty.call(options, option)) {
	      var optionElement = document.createElement('OPTION');
	      optionElement.value = option;
	      (0, _element.fastInnerHTML)(optionElement, options[option]);
	      this.select.appendChild(optionElement);
	    }
	  }
	};
	
	SelectEditor.prototype.prepareOptions = function (optionsToPrepare) {
	  var preparedOptions = {};
	
	  if (Array.isArray(optionsToPrepare)) {
	    for (var i = 0, len = optionsToPrepare.length; i < len; i++) {
	      preparedOptions[optionsToPrepare[i]] = optionsToPrepare[i];
	    }
	  } else if ((typeof optionsToPrepare === 'undefined' ? 'undefined' : _typeof(optionsToPrepare)) == 'object') {
	    preparedOptions = optionsToPrepare;
	  }
	
	  return preparedOptions;
	};
	
	SelectEditor.prototype.getValue = function () {
	  return this.select.value;
	};
	
	SelectEditor.prototype.setValue = function (value) {
	  this.select.value = value;
	};
	
	var onBeforeKeyDown = function onBeforeKeyDown(event) {
	  var instance = this;
	  var editor = instance.getActiveEditor();
	
	  switch (event.keyCode) {
	    case _unicode.KEY_CODES.ARROW_UP:
	      var previousOptionIndex = editor.select.selectedIndex - 1;
	      if (previousOptionIndex >= 0) {
	        editor.select[previousOptionIndex].selected = true;
	      }
	
	      (0, _event.stopImmediatePropagation)(event);
	      event.preventDefault();
	      break;
	
	    case _unicode.KEY_CODES.ARROW_DOWN:
	      var nextOptionIndex = editor.select.selectedIndex + 1;
	      if (nextOptionIndex <= editor.select.length - 1) {
	        editor.select[nextOptionIndex].selected = true;
	      }
	
	      (0, _event.stopImmediatePropagation)(event);
	      event.preventDefault();
	      break;
	    default:
	      break;
	  }
	};
	
	SelectEditor.prototype.open = function () {
	  this._opened = true;
	  this.refreshDimensions();
	  this.select.style.display = '';
	  this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
	};
	
	SelectEditor.prototype.close = function () {
	  this._opened = false;
	  this.select.style.display = 'none';
	  this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
	};
	
	SelectEditor.prototype.focus = function () {
	  this.select.focus();
	};
	
	SelectEditor.prototype.refreshValue = function () {
	  var sourceData = this.instance.getSourceDataAtCell(this.row, this.prop);
	  this.originalValue = sourceData;
	
	  this.setValue(sourceData);
	  this.refreshDimensions();
	};
	
	SelectEditor.prototype.refreshDimensions = function () {
	  if (this.state !== _baseEditor.EditorState.EDITING) {
	    return;
	  }
	  this.TD = this.getEditedCell();
	
	  // TD is outside of the viewport.
	  if (!this.TD) {
	    this.close();
	
	    return;
	  }
	  var width = (0, _element.outerWidth)(this.TD) + 1,
	      height = (0, _element.outerHeight)(this.TD) + 1,
	      currentOffset = (0, _element.offset)(this.TD),
	      containerOffset = (0, _element.offset)(this.instance.rootElement),
	      scrollableContainer = (0, _element.getScrollableElement)(this.TD),
	      editTop = currentOffset.top - containerOffset.top - 1 - (scrollableContainer.scrollTop || 0),
	      editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0),
	      editorSection = this.checkEditorSection(),
	      cssTransformOffset;
	
	  var settings = this.instance.getSettings();
	  var rowHeadersCount = settings.rowHeaders ? 1 : 0;
	  var colHeadersCount = settings.colHeaders ? 1 : 0;
	
	  switch (editorSection) {
	    case 'top':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'left':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'top-left-corner':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'bottom-left-corner':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
	      break;
	    case 'bottom':
	      cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode);
	      break;
	    default:
	      break;
	  }
	  if (this.instance.getSelected()[0] === 0) {
	    editTop += 1;
	  }
	
	  if (this.instance.getSelected()[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);
	
	  if (parseInt(cellComputedStyle.borderTopWidth, 10) > 0) {
	    height -= 1;
	  }
	  if (parseInt(cellComputedStyle.borderLeftWidth, 10) > 0) {
	    width -= 1;
	  }
	
	  selectStyle.height = height + 'px';
	  selectStyle.minWidth = width + 'px';
	  selectStyle.top = editTop + 'px';
	  selectStyle.left = editLeft + 'px';
	  selectStyle.margin = '0px';
	};
	
	SelectEditor.prototype.getEditedCell = function () {
	  var editorSection = this.checkEditorSection(),
	      editedCell;
	
	  switch (editorSection) {
	    case 'top':
	      editedCell = this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.select.style.zIndex = 101;
	      break;
	    case 'corner':
	      editedCell = this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.select.style.zIndex = 103;
	      break;
	    case 'left':
	      editedCell = this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.getCell({
	        row: this.row,
	        col: this.col
	      });
	      this.select.style.zIndex = 102;
	      break;
	    default:
	      editedCell = this.instance.getCell(this.row, this.col);
	      this.select.style.zIndex = '';
	      break;
	  }
	
	  return editedCell != -1 && editedCell != -2 ? editedCell : void 0;
	};
	
	exports.default = SelectEditor;
	
	/***/ }),
	/* 220 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	function cellDecorator(instance, TD, row, col, prop, value, cellProperties) {
	  if (cellProperties.className) {
	    if (TD.className) {
	      TD.className = TD.className + ' ' + cellProperties.className;
	    } else {
	      TD.className = cellProperties.className;
	    }
	  }
	
	  if (cellProperties.readOnly) {
	    (0, _element.addClass)(TD, cellProperties.readOnlyCellClassName);
	  }
	
	  if (cellProperties.valid === false && cellProperties.invalidCellClassName) {
	    (0, _element.addClass)(TD, cellProperties.invalidCellClassName);
	  } else {
	    (0, _element.removeClass)(TD, cellProperties.invalidCellClassName);
	  }
	
	  if (cellProperties.wordWrap === false && cellProperties.noWordWrapClassName) {
	    (0, _element.addClass)(TD, cellProperties.noWordWrapClassName);
	  }
	
	  if (!value && cellProperties.placeholder) {
	    (0, _element.addClass)(TD, cellProperties.placeholderCellClassName);
	  }
	} /**
	   * Adds appropriate CSS class to table cell, based on cellProperties
	   */
	exports.default = cellDecorator;
	
	/***/ }),
	/* 221 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _src = __webpack_require__(12);
	
	var _index = __webpack_require__(8);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	var clonableWRAPPER = document.createElement('DIV');
	clonableWRAPPER.className = 'htAutocompleteWrapper';
	
	var clonableARROW = document.createElement('DIV');
	clonableARROW.className = 'htAutocompleteArrow';
	// 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
	clonableARROW.appendChild(document.createTextNode(String.fromCharCode(9660)));
	
	var wrapTdContentWithWrapper = function wrapTdContentWithWrapper(TD, WRAPPER) {
	  WRAPPER.innerHTML = TD.innerHTML;
	  (0, _element.empty)(TD);
	  TD.appendChild(WRAPPER);
	};
	
	/**
	 * 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 WRAPPER = clonableWRAPPER.cloneNode(true); // this is faster than createElement
	  var ARROW = clonableARROW.cloneNode(true); // this is faster than createElement
	
	  if (cellProperties.allowHtml) {
	    (0, _index.getRenderer)('html').apply(this, arguments);
	  } else {
	    (0, _index.getRenderer)('text').apply(this, arguments);
	  }
	
	  TD.appendChild(ARROW);
	  (0, _element.addClass)(TD, 'htAutocomplete');
	
	  if (!TD.firstChild) {
	    // http://jsperf.com/empty-node-if-needed
	    // otherwise empty fields appear borderless in demo/renderers.html (IE)
	    TD.appendChild(document.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
	  }
	
	  if (!instance.acArrowListener) {
	    var eventManager = new _eventManager2.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();
	    });
	  }
	}
	
	exports.default = autocompleteRenderer;
	
	/***/ }),
	/* 222 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _string = __webpack_require__(32);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _unicode = __webpack_require__(18);
	
	var _function = __webpack_require__(35);
	
	var _event = __webpack_require__(10);
	
	var _index = __webpack_require__(8);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	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) {
	  (0, _index.getRenderer)('base').apply(this, arguments);
	
	  var eventManager = registerEvents(instance);
	  var input = createInput();
	  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(labelText);
	
	    if (labelOptions.position === 'before') {
	      label.appendChild(input);
	    } else {
	      label.insertBefore(input, label.firstChild);
	    }
	    input = label;
	  }
	
	  TD.appendChild(input);
	
	  if (badValue) {
	    TD.appendChild(document.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 (isKeyCode(toggleKeys + '|' + 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.getSelectedRange();
	
	    if (!selRange) {
	      return;
	    }
	
	    var topLeft = selRange.getTopLeftCorner();
	    var bottomRight = selRange.getBottomRightCorner();
	    var changes = [];
	
	    for (var _row = topLeft.row; _row <= bottomRight.row; _row += 1) {
	      for (var _col = topLeft.col; _col <= bottomRight.col; _col += 1) {
	        var _cellProperties = instance.getCellMeta(_row, _col);
	
	        if (_cellProperties.type !== 'checkbox') {
	          return;
	        }
	
	        /* eslint-disable no-continue */
	        if (_cellProperties.readOnly === true) {
	          continue;
	        }
	
	        if (typeof _cellProperties.checkedTemplate === 'undefined') {
	          _cellProperties.checkedTemplate = true;
	        }
	        if (typeof _cellProperties.uncheckedTemplate === 'undefined') {
	          _cellProperties.uncheckedTemplate = false;
	        }
	
	        var dataAtCell = instance.getDataAtCell(_row, _col);
	
	        if (uncheckCheckbox === false) {
	          if (dataAtCell === _cellProperties.checkedTemplate) {
	            changes.push([_row, _col, _cellProperties.uncheckedTemplate]);
	          } else if ([_cellProperties.uncheckedTemplate, null, void 0].indexOf(dataAtCell) !== -1) {
	            changes.push([_row, _col, _cellProperties.checkedTemplate]);
	          }
	        } else {
	          changes.push([_row, _col, _cellProperties.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.getSelectedRange();
	
	    if (!selRange) {
	      return;
	    }
	    var topLeft = selRange.getTopLeftCorner();
	    var bottomRight = selRange.getBottomRightCorner();
	
	    for (var _row2 = topLeft.row; _row2 <= bottomRight.row; _row2++) {
	      for (var _col2 = topLeft.col; _col2 <= bottomRight.col; _col2++) {
	        var _cellProperties2 = instance.getCellMeta(_row2, _col2);
	
	        if (_cellProperties2.type !== 'checkbox') {
	          return;
	        }
	
	        var cell = instance.getCell(_row2, _col2);
	
	        if (cell == null) {
	
	          callback(_row2, _col2, _cellProperties2);
	        } else {
	          var checkboxes = cell.querySelectorAll('input[type=checkbox]');
	
	          if (checkboxes.length > 0 && !_cellProperties2.readOnly) {
	            callback(checkboxes);
	          }
	        }
	      }
	    }
	  }
	}
	
	/**
	 * Register checkbox listeners.
	 *
	 * @param {Handsontable} instance Handsontable instance.
	 * @returns {EventManager}
	 */
	function registerEvents(instance) {
	  var eventManager = isCheckboxListenerAdded.get(instance);
	
	  if (!eventManager) {
	    eventManager = new _eventManager2.default(instance);
	    eventManager.addEventListener(instance.rootElement, 'click', function (event) {
	      return onClick(event, instance);
	    });
	    eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) {
	      return onMouseUp(event, instance);
	    });
	    eventManager.addEventListener(instance.rootElement, 'change', function (event) {
	      return onChange(event, instance);
	    });
	
	    isCheckboxListenerAdded.set(instance, eventManager);
	  }
	
	  return eventManager;
	}
	
	/**
	 * Create input element.
	 *
	 * @returns {Node}
	 */
	function createInput() {
	  var input = document.createElement('input');
	
	  input.className = 'htCheckboxRendererInput';
	  input.type = 'checkbox';
	  input.setAttribute('autocomplete', 'off');
	  input.setAttribute('tabindex', '-1');
	
	  return input.cloneNode(false);
	}
	
	/**
	 * Create label element.
	 *
	 * @returns {Node}
	 */
	function createLabel(text) {
	  var label = document.createElement('label');
	
	  label.className = 'htCheckboxRendererLabel';
	  label.appendChild(document.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';
	}
	
	exports.default = checkboxRenderer;
	
	/***/ }),
	/* 223 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _index = __webpack_require__(8);
	
	/**
	 * @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, cellProperties) {
	  (0, _index.getRenderer)('base').apply(this, arguments);
	
	  if (value === null || value === void 0) {
	    value = '';
	  }
	
	  (0, _element.fastInnerHTML)(TD, value);
	}
	
	exports.default = htmlRenderer;
	
	/***/ }),
	/* 224 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _numbro = __webpack_require__(80);
	
	var _numbro2 = _interopRequireDefault(_numbro);
	
	var _index = __webpack_require__(8);
	
	var _number = __webpack_require__(6);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * Numeric cell renderer
	 *
	 * @private
	 * @renderer NumericRenderer
	 * @dependencies numbro
	 * @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) {
	  if ((0, _number.isNumeric)(value)) {
	    if (typeof cellProperties.language !== 'undefined') {
	      _numbro2.default.culture(cellProperties.language);
	    }
	
	    value = (0, _numbro2.default)(value).format(cellProperties.format || '0');
	
	    var className = cellProperties.className || '';
	
	    var classArr = className.length ? className.split(' ') : [];
	
	    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, value, cellProperties);
	}
	
	exports.default = numericRenderer;
	
	/***/ }),
	/* 225 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _index = __webpack_require__(8);
	
	var _number = __webpack_require__(6);
	
	/**
	 * @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) {
	  (0, _index.getRenderer)('text').apply(this, arguments);
	
	  value = TD.innerHTML;
	
	  var hashLength = cellProperties.hashLength || value.length;
	  var hashSymbol = cellProperties.hashSymbol || '*';
	
	  var hash = '';
	
	  (0, _number.rangeEach)(hashLength - 1, function () {
	    hash += hashSymbol;
	  });
	  (0, _element.fastInnerHTML)(TD, hash);
	}
	
	exports.default = passwordRenderer;
	
	/***/ }),
	/* 226 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _element = __webpack_require__(0);
	
	var _mixed = __webpack_require__(22);
	
	var _index = __webpack_require__(8);
	
	/**
	 * 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) {
	  (0, _index.getRenderer)('base').apply(this, arguments);
	
	  if (!value && cellProperties.placeholder) {
	    value = cellProperties.placeholder;
	  }
	
	  var escaped = (0, _mixed.stringify)(value);
	
	  if (!instance.getSettings().trimWhitespace) {
	    escaped = escaped.replace(/ /g, String.fromCharCode(160));
	  }
	
	  if (cellProperties.rendererTemplate) {
	    (0, _element.empty)(TD);
	    var TEMPLATE = document.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);
	  }
	}
	
	exports.default = textRenderer;
	
	/***/ }),
	/* 227 */
	/***/ (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) {
	  if (value == null) {
	    value = '';
	  }
	
	  if (this.allowEmpty && value === '') {
	    callback(true);
	
	    return;
	  }
	
	  if (this.strict && this.source) {
	    if (typeof this.source === 'function') {
	      this.source(value, process(value, callback));
	    } else {
	      process(value, 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);
	  };
	}
	
	/***/ }),
	/* 228 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = dateValidator;
	exports.correctFormat = correctFormat;
	
	var _moment = __webpack_require__(50);
	
	var _moment2 = _interopRequireDefault(_moment);
	
	var _date = __webpack_require__(170);
	
	var _editors = __webpack_require__(15);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * Date cell validator
	 *
	 * @private
	 * @validator DateValidator
	 * @dependencies moment
	 * @param {*} value - Value of edited cell
	 * @param {Function} callback - Callback called with validation result
	 */
	function dateValidator(value, callback) {
	  var valid = true;
	  var dateEditor = (0, _editors.getEditorInstance)('date', this.instance);
	
	  if (value == null) {
	    value = '';
	  }
	  var isValidDate = (0, _moment2.default)(new Date(value)).isValid() || (0, _moment2.default)(value, dateEditor.defaultDateFormat).isValid();
	  // is it in the specified format
	  var isValidFormat = (0, _moment2.default)(value, this.dateFormat || dateEditor.defaultDateFormat, true).isValid();
	
	  if (this.allowEmpty && value === '') {
	    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(value, 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, _moment2.default)((0, _date.getNormalizedDate)(value));
	  var dateFromMoment = (0, _moment2.default)(value, dateFormat);
	  var isAlphanumeric = value.search(/[A-z]/g) > -1;
	  var date = void 0;
	
	  if (dateFromDate.isValid() && dateFromDate.format('x') === dateFromMoment.format('x') || !dateFromMoment.isValid() || isAlphanumeric) {
	    date = dateFromDate;
	  } else {
	    date = dateFromMoment;
	  }
	
	  return date.format(dateFormat);
	};
	
	/***/ }),
	/* 229 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = numericValidator;
	/**
	 * Numeric cell validator
	 *
	 * @private
	 * @validator NumericValidator
	 * @param {*} value - Value of edited cell
	 * @param {*} callback - Callback called with validation result
	 */
	function numericValidator(value, callback) {
	  if (value == null) {
	    value = '';
	  }
	  if (this.allowEmpty && value === '') {
	    callback(true);
	  } else if (value === '') {
	    callback(false);
	  } else {
	    callback(/^-?\d*(\.|,)?\d*$/.test(value));
	  }
	};
	
	/***/ }),
	/* 230 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = timeValidator;
	
	var _moment = __webpack_require__(50);
	
	var _moment2 = _interopRequireDefault(_moment);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	// 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
	 * @dependencies moment
	 * @param {*} value - Value of edited cell
	 * @param {Function} callback - Callback called with validation result
	 */
	function timeValidator(value, callback) {
	  var valid = true;
	  var timeFormat = this.timeFormat || 'h:mm:ss a';
	
	  if (value === null) {
	    value = '';
	  }
	
	  value = /^\d{3,}$/.test(value) ? parseInt(value, 10) : value;
	
	  var twoDigitValue = /^\d{1,2}$/.test(value);
	
	  if (twoDigitValue) {
	    value += ':00';
	  }
	
	  var date = (0, _moment2.default)(value, STRICT_FORMATS, true).isValid() ? (0, _moment2.default)(value) : (0, _moment2.default)(value, timeFormat);
	  var isValidTime = date.isValid();
	
	  // is it in the specified format
	  var isValidFormat = (0, _moment2.default)(value, timeFormat, true).isValid() && !twoDigitValue;
	
	  if (this.allowEmpty && value === '') {
	    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);
	};
	
	/***/ }),
	/* 231 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var CELL_TYPE = 'autocomplete';
	
	exports.default = {
	  editor: (0, _editors.getEditor)(CELL_TYPE),
	  renderer: (0, _renderers.getRenderer)(CELL_TYPE),
	  validator: (0, _validators.getValidator)(CELL_TYPE)
	};
	
	/***/ }),
	/* 232 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var CELL_TYPE = 'checkbox';
	
	exports.default = {
	  editor: (0, _editors.getEditor)(CELL_TYPE),
	  renderer: (0, _renderers.getRenderer)(CELL_TYPE)
	};
	
	/***/ }),
	/* 233 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var CELL_TYPE = 'date';
	
	exports.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)
	};
	
	/***/ }),
	/* 234 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var CELL_TYPE = 'dropdown';
	
	exports.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')
	};
	
	/***/ }),
	/* 235 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var CELL_TYPE = 'handsontable';
	
	exports.default = {
	  editor: (0, _editors.getEditor)(CELL_TYPE),
	  // displays small gray arrow on right side of the cell
	  renderer: (0, _renderers.getRenderer)('autocomplete')
	};
	
	/***/ }),
	/* 236 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var CELL_TYPE = 'numeric';
	
	exports.default = {
	  editor: (0, _editors.getEditor)(CELL_TYPE),
	  renderer: (0, _renderers.getRenderer)(CELL_TYPE),
	  validator: (0, _validators.getValidator)(CELL_TYPE),
	  dataType: 'number'
	};
	
	/***/ }),
	/* 237 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var CELL_TYPE = 'password';
	
	exports.default = {
	  editor: (0, _editors.getEditor)(CELL_TYPE),
	  renderer: (0, _renderers.getRenderer)(CELL_TYPE),
	  copyable: false
	};
	
	/***/ }),
	/* 238 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _browser = __webpack_require__(26);
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var CELL_TYPE = 'text';
	
	exports.default = {
	  editor: (0, _browser.isMobileBrowser)() ? (0, _editors.getEditor)('mobile') : (0, _editors.getEditor)(CELL_TYPE),
	  renderer: (0, _renderers.getRenderer)(CELL_TYPE)
	};
	
	/***/ }),
	/* 239 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _editors = __webpack_require__(15);
	
	var _renderers = __webpack_require__(8);
	
	var _validators = __webpack_require__(27);
	
	var CELL_TYPE = 'time';
	
	exports.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)
	};
	
	/***/ }),
	/* 240 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _SheetClip = __webpack_require__(171);
	
	var _SheetClip2 = _interopRequireDefault(_SheetClip);
	
	var _data = __webpack_require__(84);
	
	var _setting = __webpack_require__(83);
	
	var _object = __webpack_require__(1);
	
	var _array = __webpack_require__(2);
	
	var _interval = __webpack_require__(241);
	
	var _interval2 = _interopRequireDefault(_interval);
	
	var _number = __webpack_require__(6);
	
	var _multiMap = __webpack_require__(242);
	
	var _multiMap2 = _interopRequireDefault(_multiMap);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * 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
	 *
	 * @param {Object} instance Instance of Handsontable
	 * @param {*} priv
	 * @param {*} GridSettings Grid settings
	 * @util
	 * @class DataMap
	 */
	function DataMap(instance, priv, GridSettings) {
	  var _this = this;
	
	  this.instance = instance;
	  this.priv = priv;
	  this.GridSettings = GridSettings;
	  this.dataSource = this.instance.getSettings().data;
	  this.cachedLength = null;
	  this.skipCache = false;
	  this.latestSourceRowsCount = 0;
	
	  if (this.dataSource && this.dataSource[0]) {
	    this.duckSchema = this.recursiveDuckSchema(this.dataSource[0]);
	  } else {
	    this.duckSchema = {};
	  }
	  this.createMap();
	  this.interval = _interval2.default.create(function () {
	    return _this.clearLengthCache();
	  }, '15fps');
	
	  this.instance.addHook('skipLengthCache', function (delay) {
	    return _this.onSkipLengthCache(delay);
	  });
	  this.onSkipLengthCache(500);
	}
	
	DataMap.prototype.DESTINATION_RENDERER = 1;
	DataMap.prototype.DESTINATION_CLIPBOARD_GENERATOR = 2;
	
	/**
	 * @param {Object|Array} object
	 * @returns {Object|Array}
	 */
	DataMap.prototype.recursiveDuckSchema = function (object) {
	  return (0, _object.duckSchema)(object);
	};
	
	/**
	 * @param {Object} schema
	 * @param {Number} lastCol
	 * @param {Number} parent
	 * @returns {Number}
	 */
	DataMap.prototype.recursiveDuckColumns = function (schema, lastCol, parent) {
	  var prop, i;
	  if (typeof lastCol === 'undefined') {
	    lastCol = 0;
	    parent = '';
	  }
	  if ((typeof schema === 'undefined' ? 'undefined' : _typeof(schema)) === 'object' && !Array.isArray(schema)) {
	    for (i in schema) {
	      if ((0, _object.hasOwnProperty)(schema, i)) {
	        if (schema[i] === null) {
	          prop = parent + i;
	          this.colToPropCache.push(prop);
	          this.propToColCache.set(prop, lastCol);
	
	          lastCol++;
	        } else {
	          lastCol = this.recursiveDuckColumns(schema[i], lastCol, i + '.');
	        }
	      }
	    }
	  }
	
	  return lastCol;
	};
	
	DataMap.prototype.createMap = function () {
	  var i = void 0;
	  var schema = this.getSchema();
	
	  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 _multiMap2.default();
	
	  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++;
	      }
	    }
	  } else {
	    this.recursiveDuckColumns(schema);
	  }
	};
	
	/**
	 * Returns property name that corresponds with the given column index.
	 *
	 * @param {Number} col Visual column index.
	 * @returns {Number} Physical column index.
	 */
	DataMap.prototype.colToProp = function (col) {
	  col = this.instance.runHooks('modifyCol', col);
	
	  if (!isNaN(col) && this.colToPropCache && typeof this.colToPropCache[col] !== 'undefined') {
	    return this.colToPropCache[col];
	  }
	
	  return col;
	};
	
	/**
	 * @param {Object} prop
	 * @fires Hooks#modifyCol
	 * @returns {*}
	 */
	DataMap.prototype.propToCol = function (prop) {
	  var col;
	
	  if (typeof this.propToColCache.get(prop) === 'undefined') {
	    col = prop;
	  } else {
	    col = this.propToColCache.get(prop);
	  }
	  col = this.instance.runHooks('unmodifyCol', col);
	
	  return col;
	};
	
	/**
	 * @returns {Object}
	 */
	DataMap.prototype.getSchema = function () {
	  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] An amount of rows to add.
	 * @param {String} [source] Source of method call.
	 * @fires Hooks#afterCreateRow
	 * @returns {Number} Returns number of created rows.
	 */
	DataMap.prototype.createRow = function (index, amount, source) {
	  var row,
	      colCount = this.instance.countCols(),
	      numberOfCreatedRows = 0,
	      currentIndex;
	
	  if (!amount) {
	    amount = 1;
	  }
	
	  if (typeof index !== 'number' || index >= this.instance.countSourceRows()) {
	    index = this.instance.countSourceRows();
	  }
	  this.instance.runHooks('beforeCreateRow', index, amount, source);
	
	  currentIndex = index;
	  var maxRows = this.instance.getSettings().maxRows;
	
	  while (numberOfCreatedRows < amount && this.instance.countSourceRows() < maxRows) {
	    if (this.instance.dataType === 'array') {
	      if (this.instance.getSettings().dataSchema) {
	        // Clone template array
	        row = (0, _object.deepClone)(this.getSchema());
	      } else {
	        row = [];
	        /* eslint-disable no-loop-func */
	        (0, _number.rangeEach)(colCount - 1, function () {
	          return row.push(null);
	        });
	      }
	    } else if (this.instance.dataType === 'function') {
	      row = this.instance.getSettings().dataSchema(index);
	    } else {
	      row = {};
	      (0, _object.deepExtend)(row, this.getSchema());
	    }
	
	    if (index === this.instance.countSourceRows()) {
	      this.dataSource.push(row);
	    } else {
	      this.spliceData(index, 0, row);
	    }
	
	    numberOfCreatedRows++;
	    currentIndex++;
	  }
	
	  this.instance.runHooks('afterCreateRow', index, numberOfCreatedRows, source);
	  this.instance.forceFullRender = true; // used when data was changed
	
	  return numberOfCreatedRows;
	};
	
	/**
	 * Creates col 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] An amount of columns to add.
	 * @param {String} [source] Source of method call.
	 * @fires Hooks#afterCreateCol
	 * @returns {Number} Returns number of created columns
	 */
	DataMap.prototype.createCol = function (index, amount, source) {
	  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(),
	      data = this.dataSource,
	      constructor,
	      numberOfCreatedCols = 0,
	      currentIndex;
	
	  if (!amount) {
	    amount = 1;
	  }
	
	  if (typeof index !== 'number' || index >= this.instance.countCols()) {
	    index = this.instance.countCols();
	  }
	  this.instance.runHooks('beforeCreateCol', index, amount, source);
	
	  currentIndex = index;
	
	  var maxCols = this.instance.getSettings().maxCols;
	  while (numberOfCreatedCols < amount && this.instance.countCols() < maxCols) {
	    constructor = (0, _setting.columnFactory)(this.GridSettings, this.priv.columnsSettingConflicts);
	
	    if (typeof index !== 'number' || index >= 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 _r = 0; _r < rlen; _r++) {
	        data[_r].splice(currentIndex, 0, null);
	      }
	      // Add new column constructor at given index
	      this.priv.columnSettings.splice(currentIndex, 0, constructor);
	    }
	
	    numberOfCreatedCols++;
	    currentIndex++;
	  }
	
	  this.instance.runHooks('afterCreateCol', index, 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] 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
	 */
	DataMap.prototype.removeRow = function (index, amount, source) {
	  if (!amount) {
	    amount = 1;
	  }
	  if (typeof index !== 'number') {
	    index = -amount;
	  }
	
	  amount = this.instance.runHooks('modifyRemovedAmount', amount, index);
	
	  index = (this.instance.countSourceRows() + index) % this.instance.countSourceRows();
	
	  var logicRows = this.visualRowsToPhysical(index, amount);
	  var actionWasNotCancelled = this.instance.runHooks('beforeRemoveRow', index, amount, logicRows, source);
	
	  if (actionWasNotCancelled === false) {
	    return;
	  }
	
	  var data = this.dataSource;
	  var newData = void 0;
	
	  newData = this.filterData(index, amount);
	
	  if (newData) {
	    data.length = 0;
	    Array.prototype.push.apply(data, newData);
	  }
	
	  this.instance.runHooks('afterRemoveRow', index, amount, 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] 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
	 */
	DataMap.prototype.removeCol = function (index, amount, source) {
	  if (this.instance.dataType === 'object' || this.instance.getSettings().columns) {
	    throw new Error('cannot remove column with object data source or columns option specified');
	  }
	  if (!amount) {
	    amount = 1;
	  }
	  if (typeof index !== 'number') {
	    index = -amount;
	  }
	
	  index = (this.instance.countCols() + index) % this.instance.countCols();
	
	  var logicColumns = this.visualColumnsToPhysical(index, amount);
	  var descendingLogicColumns = logicColumns.slice(0).sort(function (a, b) {
	    return b - a;
	  });
	  var actionWasNotCancelled = this.instance.runHooks('beforeRemoveCol', index, 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 _r2 = 0, _rlen = this.instance.countSourceRows(); _r2 < _rlen; _r2++) {
	      for (var _c = 0; _c < removedColumnsCount; _c++) {
	        data[_r2].splice(descendingLogicColumns[_c], 1);
	      }
	    }
	
	    for (var _c2 = 0; _c2 < removedColumnsCount; _c2++) {
	      this.priv.columnSettings.splice(logicColumns[_c2], 1);
	    }
	  }
	
	  this.instance.runHooks('afterRemoveCol', index, 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
	 * @returns {Array} Returns removed portion of columns
	 */
	DataMap.prototype.spliceCol = function (col, index, amount /* , elements... */) {
	  var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : [];
	
	  var colData = this.instance.getDataAtCol(col);
	  var removed = colData.slice(index, index + amount);
	  var after = colData.slice(index + amount);
	
	  (0, _array.extendArray)(elements, after);
	  var i = 0;
	  while (i < amount) {
	    elements.push(null); // add null in place of removed elements
	    i++;
	  }
	  (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.
	 * @returns {Array} Returns removed portion of rows
	 */
	DataMap.prototype.spliceRow = function (row, index, amount /* , elements... */) {
	  var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : [];
	
	  var rowData = this.instance.getSourceDataAtRow(row);
	  var removed = rowData.slice(index, index + amount);
	  var after = rowData.slice(index + amount);
	
	  (0, _array.extendArray)(elements, after);
	  var i = 0;
	  while (i < amount) {
	    elements.push(null); // add null in place of removed elements
	    i++;
	  }
	  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.
	 */
	DataMap.prototype.spliceData = function (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}
	 */
	DataMap.prototype.filterData = function (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, index) {
	      return physicalRows.indexOf(index) == -1;
	    });
	
	    return newData;
	  }
	};
	
	/**
	 * Returns single value from the data array.
	 *
	 * @param {Number} row Visual row index.
	 * @param {Number} prop
	 */
	DataMap.prototype.get = function (row, prop) {
	  row = this.instance.runHooks('modifyRow', row);
	
	  var dataRow = this.dataSource[row];
	  // TODO: To remove, use 'modifyData' hook instead (see below)
	  var modifiedRowData = this.instance.runHooks('modifyRowData', row);
	
	  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(row, row + 1)[0]);
	  }
	
	  if (this.instance.hasHook('modifyData')) {
	    var valueHolder = (0, _object.createObjectPropListener)(value);
	
	    this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'get');
	
	    if (valueHolder.isTouched()) {
	      value = valueHolder.value;
	    }
	  }
	
	  return value;
	};
	
	var copyableLookup = (0, _data.cellMethodLookupFactory)('copyable', false);
	
	/**
	 * 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}
	 */
	DataMap.prototype.getCopyable = function (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.
	 */
	DataMap.prototype.set = function (row, prop, value, source) {
	  row = this.instance.runHooks('modifyRow', row, source || 'datamapGet');
	
	  var dataRow = this.dataSource[row];
	  // TODO: To remove, use 'modifyData' hook instead (see below)
	  var modifiedRowData = this.instance.runHooks('modifyRowData', row);
	
	  dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow;
	  //
	
	  if (this.instance.hasHook('modifyData')) {
	    var valueHolder = (0, _object.createObjectPropListener)(value);
	
	    this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'set');
	
	    if (valueHolder.isTouched()) {
	      value = valueHolder.value;
	    }
	  }
	
	  // try to set value under property `prop` (includes dot)
	  if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) {
	    dataRow[prop] = value;
	  } else if (typeof prop === 'string' && prop.indexOf('.') > -1) {
	    var sliced = prop.split('.');
	    var out = dataRow;
	    var i = 0;
	    var ilen = void 0;
	
	    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]] = value;
	  } else if (typeof prop === 'function') {
	    /* see the `function` handler in `get` */
	    prop(this.dataSource.slice(row, row + 1)[0], value);
	  } else {
	    dataRow[prop] = value;
	  }
	};
	
	/**
	 * 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}
	 */
	DataMap.prototype.visualRowsToPhysical = function (index, amount) {
	  var totalRows = this.instance.countSourceRows();
	  var physicRow = (totalRows + index) % totalRows;
	  var logicRows = [];
	  var rowsToRemove = amount;
	  var row;
	
	  while (physicRow < totalRows && rowsToRemove) {
	    row = this.instance.runHooks('modifyRow', physicRow);
	    logicRows.push(row);
	
	    rowsToRemove--;
	    physicRow++;
	  }
	
	  return logicRows;
	};
	
	/**
	 *
	 * @param index Visual column index.
	 * @param amount
	 * @returns {Array}
	 */
	DataMap.prototype.visualColumnsToPhysical = function (index, amount) {
	  var totalCols = this.instance.countCols();
	  var physicalCol = (totalCols + index) % totalCols;
	  var visualCols = [];
	  var colsToRemove = amount;
	
	  while (physicalCol < totalCols && colsToRemove) {
	    var col = this.instance.runHooks('modifyCol', physicalCol);
	
	    visualCols.push(col);
	
	    colsToRemove--;
	    physicalCol++;
	  }
	
	  return visualCols;
	};
	
	/**
	 * Clears the data array.
	 */
	DataMap.prototype.clear = function () {
	  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.
	 */
	DataMap.prototype.clearLengthCache = function () {
	  this.cachedLength = null;
	};
	
	/**
	 * Get data length.
	 *
	 * @returns {Number}
	 */
	DataMap.prototype.getLength = function () {
	  var _this2 = this;
	
	  var maxRows = void 0,
	      maxRowsFromSettings = this.instance.getSettings().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) {
	        row = _this2.instance.runHooks('modifyRow', row);
	
	        if (row === null) {
	          --length;
	        }
	      });
	      this.cachedLength = length;
	    } else {
	      length = this.cachedLength;
	    }
	  } else {
	    this.interval.stop();
	  }
	
	  return Math.min(length, maxRows);
	};
	
	/**
	 * Returns the data array.
	 *
	 * @returns {Array}
	 */
	DataMap.prototype.getAll = function () {
	  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.prototype.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}
	 */
	DataMap.prototype.getRange = function (start, end, destination) {
	  var r,
	      rlen,
	      c,
	      clen,
	      output = [],
	      row;
	
	  var maxRows = this.instance.getSettings().maxRows;
	  var maxCols = this.instance.getSettings().maxCols;
	
	  if (maxRows === 0 || maxCols === 0) {
	    return [];
	  }
	
	  var getFn = destination === this.DESTINATION_CLIPBOARD_GENERATOR ? this.getCopyable : this.get;
	
	  rlen = Math.min(Math.max(maxRows - 1, 0), Math.max(start.row, end.row));
	  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.runHooks('modifyRow', 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}
	 */
	DataMap.prototype.getText = function (start, end) {
	  return _SheetClip2.default.stringify(this.getRange(start, end, this.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}
	 */
	DataMap.prototype.getCopyableText = function (start, end) {
	  return _SheetClip2.default.stringify(this.getRange(start, end, this.DESTINATION_CLIPBOARD_GENERATOR));
	};
	
	/**
	 * `skipLengthCache` callback.
	 * @private
	 * @param {Number} delay Time of the delay in milliseconds.
	 */
	DataMap.prototype.onSkipLengthCache = function (delay) {
	  var _this3 = this;
	
	  this.skipCache = true;
	  setTimeout(function () {
	    _this3.skipCache = false;
	  }, delay);
	};
	
	/**
	 * Destroy instance.
	 */
	DataMap.prototype.destroy = function () {
	  this.interval.stop();
	
	  this.interval = null;
	  this.instance = null;
	  this.priv = null;
	  this.GridSettings = null;
	  this.dataSource = null;
	  this.cachedLength = null;
	  this.duckSchema = null;
	};
	
	exports.default = DataMap;
	
	/***/ }),
	/* 241 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	exports.parseDelay = parseDelay;
	
	var _feature = __webpack_require__(34);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class Interval
	 * @util
	 */
	var Interval = function () {
	  _createClass(Interval, null, [{
	    key: 'create',
	    value: function create(func, delay) {
	      return new Interval(func, delay);
	    }
	  }]);
	
	  function Interval(func, delay) {
	    var _this = this;
	
	    _classCallCheck(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}
	   */
	
	
	  _createClass(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;
	}();
	
	exports.default = Interval;
	function parseDelay(delay) {
	  if (typeof delay === 'string' && /fps$/.test(delay)) {
	    delay = 1000 / parseInt(delay.replace('fps', '') || 0, 10);
	  }
	
	  return delay;
	}
	
	/***/ }),
	/* 242 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	function MultiMap() {
	  var map = {
	    arrayMap: [],
	    weakMap: new WeakMap()
	  };
	
	  return {
	    get: function get(key) {
	      if (canBeAnArrayMapKey(key)) {
	        return map.arrayMap[key];
	      } else if (canBeAWeakMapKey(key)) {
	        return map.weakMap.get(key);
	      }
	    },
	    set: function set(key, value) {
	      if (canBeAnArrayMapKey(key)) {
	        map.arrayMap[key] = value;
	      } else if (canBeAWeakMapKey(key)) {
	        map.weakMap.set(key, value);
	      } else {
	        throw new Error('Invalid key type');
	      }
	    },
	    delete: function _delete(key) {
	      if (canBeAnArrayMapKey(key)) {
	        delete map.arrayMap[key];
	      } else if (canBeAWeakMapKey(key)) {
	        map.weakMap.delete(key);
	      }
	    }
	  };
	
	  function canBeAnArrayMapKey(obj) {
	    return obj !== null && !isNaNSymbol(obj) && (typeof obj == 'string' || typeof obj == 'number');
	  }
	
	  function canBeAWeakMapKey(obj) {
	    return obj !== null && ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) == 'object' || typeof obj == 'function');
	  }
	
	  function isNaNSymbol(obj) {
	    /* eslint-disable no-self-compare */
	    return obj !== obj; // NaN === NaN is always false
	  }
	}
	
	exports.default = MultiMap;
	
	/***/ }),
	/* 243 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _src = __webpack_require__(12);
	
	var _unicode = __webpack_require__(18);
	
	var _event = __webpack_require__(10);
	
	var _editors = __webpack_require__(15);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _baseEditor = __webpack_require__(41);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function EditorManager(instance, priv, selection) {
	  var _this = this,
	      destroyed = false,
	      eventManager,
	      activeEditor;
	
	  eventManager = new _eventManager2.default(instance);
	
	  function moveSelectionAfterEnter(shiftKey) {
	    selection.setSelectedHeaders(false, false, false);
	    var enterMoves = typeof priv.settings.enterMoves === 'function' ? priv.settings.enterMoves(event) : priv.settings.enterMoves;
	
	    if (shiftKey) {
	      // move selection up
	      selection.transformStart(-enterMoves.row, -enterMoves.col);
	    } else {
	      // move selection down (add a new row if needed)
	      selection.transformStart(enterMoves.row, enterMoves.col, true);
	    }
	  }
	
	  function moveSelectionUp(shiftKey) {
	    if (shiftKey) {
	      if (selection.selectedHeader.cols) {
	        selection.setSelectedHeaders(selection.selectedHeader.rows, false, false);
	      }
	      selection.transformEnd(-1, 0);
	    } else {
	      selection.setSelectedHeaders(false, false, false);
	      selection.transformStart(-1, 0);
	    }
	  }
	
	  function moveSelectionDown(shiftKey) {
	    if (shiftKey) {
	      // expanding selection down with shift
	      selection.transformEnd(1, 0);
	    } else {
	      selection.setSelectedHeaders(false, false, false);
	      selection.transformStart(1, 0);
	    }
	  }
	
	  function moveSelectionRight(shiftKey) {
	    if (shiftKey) {
	      selection.transformEnd(0, 1);
	    } else {
	      selection.setSelectedHeaders(false, false, false);
	      selection.transformStart(0, 1);
	    }
	  }
	
	  function moveSelectionLeft(shiftKey) {
	    if (shiftKey) {
	      if (selection.selectedHeader.rows) {
	        selection.setSelectedHeaders(false, selection.selectedHeader.cols, false);
	      }
	      selection.transformEnd(0, -1);
	    } else {
	      selection.setSelectedHeaders(false, false, false);
	      selection.transformStart(0, -1);
	    }
	  }
	
	  function onKeyDown(event) {
	    var ctrlDown, rangeModifier;
	
	    if (!instance.isListening()) {
	      return;
	    }
	    instance.runHooks('beforeKeyDown', event);
	
	    if (destroyed) {
	      return;
	    }
	    if ((0, _event.isImmediatePropagationStopped)(event)) {
	      return;
	    }
	    priv.lastKeyCode = event.keyCode;
	
	    if (!selection.isSelected()) {
	      return;
	    }
	    // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
	    ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
	
	    if (activeEditor && !activeEditor.isWaiting()) {
	      if (!(0, _unicode.isMetaKey)(event.keyCode) && !(0, _unicode.isCtrlKey)(event.keyCode) && !ctrlDown && !_this.isEditorOpened()) {
	        _this.openEditor('', event);
	
	        return;
	      }
	    }
	    rangeModifier = event.shiftKey ? selection.setRangeEnd : selection.setRangeStart;
	
	    switch (event.keyCode) {
	      case _unicode.KEY_CODES.A:
	        if (!_this.isEditorOpened() && ctrlDown) {
	          selection.selectAll();
	
	          event.preventDefault();
	          (0, _event.stopPropagation)(event);
	        }
	        break;
	
	      case _unicode.KEY_CODES.ARROW_UP:
	        if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
	          _this.closeEditorAndSaveChanges(ctrlDown);
	        }
	        moveSelectionUp(event.shiftKey);
	
	        event.preventDefault();
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.ARROW_DOWN:
	        if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
	          _this.closeEditorAndSaveChanges(ctrlDown);
	        }
	
	        moveSelectionDown(event.shiftKey);
	
	        event.preventDefault();
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.ARROW_RIGHT:
	        if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
	          _this.closeEditorAndSaveChanges(ctrlDown);
	        }
	
	        moveSelectionRight(event.shiftKey);
	
	        event.preventDefault();
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.ARROW_LEFT:
	        if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
	          _this.closeEditorAndSaveChanges(ctrlDown);
	        }
	
	        moveSelectionLeft(event.shiftKey);
	
	        event.preventDefault();
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.TAB:
	        selection.setSelectedHeaders(false, false, false);
	        var tabMoves = typeof priv.settings.tabMoves === 'function' ? priv.settings.tabMoves(event) : priv.settings.tabMoves;
	
	        if (event.shiftKey) {
	          // move selection left
	          selection.transformStart(-tabMoves.row, -tabMoves.col);
	        } else {
	          // move selection right (add a new column if needed)
	          selection.transformStart(tabMoves.row, tabMoves.col, true);
	        }
	        event.preventDefault();
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.BACKSPACE:
	      case _unicode.KEY_CODES.DELETE:
	        selection.empty(event);
	        _this.prepareEditor();
	        event.preventDefault();
	        break;
	
	      case _unicode.KEY_CODES.F2:
	        /* F2 */
	        _this.openEditor(null, event);
	
	        if (activeEditor) {
	          activeEditor.enableFullEditMode();
	        }
	        event.preventDefault(); // prevent Opera from opening 'Go to Page dialog'
	        break;
	
	      case _unicode.KEY_CODES.ENTER:
	        /* return/enter */
	        if (_this.isEditorOpened()) {
	
	          if (activeEditor && activeEditor.state !== _baseEditor.EditorState.WAITING) {
	            _this.closeEditorAndSaveChanges(ctrlDown);
	          }
	          moveSelectionAfterEnter(event.shiftKey);
	        } else if (instance.getSettings().enterBeginsEditing) {
	          _this.openEditor(null, event);
	
	          if (activeEditor) {
	            activeEditor.enableFullEditMode();
	          }
	        } else {
	          moveSelectionAfterEnter(event.shiftKey);
	        }
	        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(ctrlDown);
	        }
	        event.preventDefault();
	        break;
	
	      case _unicode.KEY_CODES.HOME:
	        selection.setSelectedHeaders(false, false, false);
	        if (event.ctrlKey || event.metaKey) {
	          rangeModifier(new _src.CellCoords(0, priv.selRange.from.col));
	        } else {
	          rangeModifier(new _src.CellCoords(priv.selRange.from.row, 0));
	        }
	        event.preventDefault(); // don't scroll the window
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.END:
	        selection.setSelectedHeaders(false, false, false);
	        if (event.ctrlKey || event.metaKey) {
	          rangeModifier(new _src.CellCoords(instance.countRows() - 1, priv.selRange.from.col));
	        } else {
	          rangeModifier(new _src.CellCoords(priv.selRange.from.row, instance.countCols() - 1));
	        }
	        event.preventDefault(); // don't scroll the window
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.PAGE_UP:
	        selection.setSelectedHeaders(false, false, false);
	        selection.transformStart(-instance.countVisibleRows(), 0);
	        event.preventDefault(); // don't page up the window
	        (0, _event.stopPropagation)(event);
	        break;
	
	      case _unicode.KEY_CODES.PAGE_DOWN:
	        selection.setSelectedHeaders(false, false, false);
	        selection.transformStart(instance.countVisibleRows(), 0);
	        event.preventDefault(); // don't page down the window
	        (0, _event.stopPropagation)(event);
	        break;
	      default:
	        break;
	    }
	  }
	
	  function init() {
	    instance.addHook('afterDocumentKeyDown', onKeyDown);
	
	    eventManager.addEventListener(document.documentElement, 'keydown', function (event) {
	      if (!destroyed) {
	        instance.runHooks('afterDocumentKeyDown', event);
	      }
	    });
	
	    function onDblClick(event, coords, elem) {
	      // may be TD or TH
	      if (elem.nodeName == 'TD') {
	        _this.openEditor();
	
	        if (activeEditor) {
	          activeEditor.enableFullEditMode();
	        }
	      }
	    }
	    instance.view.wt.update('onCellDblClick', onDblClick);
	
	    instance.addHook('afterDestroy', function () {
	      destroyed = true;
	    });
	  }
	
	  /**
	   * Destroy current editor, if exists.
	   *
	   * @function destroyEditor
	   * @memberof! Handsontable.EditorManager#
	   * @param {Boolean} revertOriginal
	   */
	  this.destroyEditor = function (revertOriginal) {
	    this.closeEditor(revertOriginal);
	  };
	
	  /**
	   * Get active editor.
	   *
	   * @function getActiveEditor
	   * @memberof! Handsontable.EditorManager#
	   * @returns {*}
	   */
	  this.getActiveEditor = function () {
	    return activeEditor;
	  };
	
	  /**
	   * Prepare text input to be displayed at given grid cell.
	   *
	   * @function prepareEditor
	   * @memberof! Handsontable.EditorManager#
	   */
	  this.prepareEditor = function () {
	    var row, col, prop, td, originalValue, cellProperties, editorClass;
	
	    if (activeEditor && activeEditor.isWaiting()) {
	      this.closeEditor(false, false, function (dataSaved) {
	        if (dataSaved) {
	          _this.prepareEditor();
	        }
	      });
	
	      return;
	    }
	    row = priv.selRange.highlight.row;
	    col = priv.selRange.highlight.col;
	    prop = instance.colToProp(col);
	    td = instance.getCell(row, col);
	
	    originalValue = instance.getSourceDataAtCell(instance.runHooks('modifyRow', row), col);
	    cellProperties = instance.getCellMeta(row, col);
	    editorClass = instance.getCellEditor(cellProperties);
	
	    if (editorClass) {
	      activeEditor = (0, _editors.getEditorInstance)(editorClass, instance);
	      activeEditor.prepare(row, col, prop, td, originalValue, cellProperties);
	    } else {
	      activeEditor = void 0;
	    }
	  };
	
	  /**
	   * Check is editor is opened/showed.
	   *
	   * @function isEditorOpened
	   * @memberof! Handsontable.EditorManager#
	   * @returns {Boolean}
	   */
	  this.isEditorOpened = function () {
	    return activeEditor && activeEditor.isOpened();
	  };
	
	  /**
	   * Open editor with initial value.
	   *
	   * @function openEditor
	   * @memberof! Handsontable.EditorManager#
	   * @param {String} initialValue
	   * @param {DOMEvent} event
	   */
	  this.openEditor = function (initialValue, event) {
	    if (activeEditor && !activeEditor.cellProperties.readOnly) {
	      activeEditor.beginEditing(initialValue, event);
	    } else if (activeEditor && activeEditor.cellProperties.readOnly) {
	
	      // move the selection after opening the editor with ENTER key
	      if (event && event.keyCode === _unicode.KEY_CODES.ENTER) {
	        moveSelectionAfterEnter();
	      }
	    }
	  };
	
	  /**
	   * Close editor, finish editing cell.
	   *
	   * @function closeEditor
	   * @memberof! Handsontable.EditorManager#
	   * @param {Boolean} restoreOriginalValue
	   * @param {Boolean} [ctrlDown]
	   * @param {Function} [callback]
	   */
	  this.closeEditor = function (restoreOriginalValue, ctrlDown, callback) {
	    if (activeEditor) {
	      activeEditor.finishEditing(restoreOriginalValue, ctrlDown, callback);
	    } else if (callback) {
	      callback(false);
	    }
	  };
	
	  /**
	   * Close editor and save changes.
	   *
	   * @function closeEditorAndSaveChanges
	   * @memberof! Handsontable.EditorManager#
	   * @param {Boolean} ctrlDown
	   */
	  this.closeEditorAndSaveChanges = function (ctrlDown) {
	    return this.closeEditor(false, ctrlDown);
	  };
	
	  /**
	   * Close editor and restore original value.
	   *
	   * @function closeEditorAndRestoreOriginalValue
	   * @memberof! Handsontable.EditorManager#
	   * @param {Boolean} ctrlDown
	   */
	  this.closeEditorAndRestoreOriginalValue = function (ctrlDown) {
	    return this.closeEditor(true, ctrlDown);
	  };
	
	  init();
	}
	
	exports.default = EditorManager;
	
	/***/ }),
	/* 244 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _slicedToArray = function () { function sliceIterator(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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	var _element = __webpack_require__(0);
	
	var _browser = __webpack_require__(26);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _event = __webpack_require__(10);
	
	var _src = __webpack_require__(12);
	
	var _src2 = _interopRequireDefault(_src);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * Handsontable TableView constructor
	 * @param {Object} instance
	 */
	function TableView(instance) {
	  var _this = this;
	
	  var that = this;
	
	  this.eventManager = new _eventManager2.default(instance);
	  this.instance = instance;
	  this.settings = instance.getSettings();
	  this.selectionMouseDown = false;
	
	  var originalStyle = instance.rootElement.getAttribute('style');
	
	  if (originalStyle) {
	    instance.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)(instance.rootElement, 'handsontable');
	
	  var table = document.createElement('TABLE');
	  (0, _element.addClass)(table, 'htCore');
	
	  if (instance.getSettings().tableClassName) {
	    (0, _element.addClass)(table, instance.getSettings().tableClassName);
	  }
	  this.THEAD = document.createElement('THEAD');
	  table.appendChild(this.THEAD);
	  this.TBODY = document.createElement('TBODY');
	  table.appendChild(this.TBODY);
	
	  instance.table = table;
	
	  instance.container.insertBefore(table, instance.container.firstChild);
	
	  this.eventManager.addEventListener(instance.rootElement, 'mousedown', function (event) {
	    this.selectionMouseDown = true;
	
	    if (!that.isTextSelectionAllowed(event.target)) {
	      clearTextSelection();
	      event.preventDefault();
	      window.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe.
	    }
	  });
	  this.eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) {
	    this.selectionMouseDown = false;
	  });
	  this.eventManager.addEventListener(instance.rootElement, 'mousemove', function (event) {
	    if (this.selectionMouseDown && !that.isTextSelectionAllowed(event.target)) {
	      clearTextSelection();
	      event.preventDefault();
	    }
	  });
	
	  this.eventManager.addEventListener(document.documentElement, 'keyup', function (event) {
	    if (instance.selection.isInProgress() && !event.shiftKey) {
	      instance.selection.finish();
	    }
	  });
	
	  var isMouseDown;
	  this.isMouseDown = function () {
	    return isMouseDown;
	  };
	
	  this.eventManager.addEventListener(document.documentElement, 'mouseup', function (event) {
	    if (instance.selection.isInProgress() && event.which === 1) {
	      // is left mouse button
	      instance.selection.finish();
	    }
	
	    isMouseDown = false;
	
	    if ((0, _element.isOutsideInput)(document.activeElement) || !instance.selection.isSelected()) {
	      instance.unlisten();
	    }
	  });
	
	  this.eventManager.addEventListener(document.documentElement, 'mousedown', function (event) {
	    var originalTarget = event.target;
	    var next = event.target;
	    var eventX = event.x || event.clientX;
	    var eventY = event.y || event.clientY;
	
	    if (isMouseDown || !instance.rootElement) {
	      return; // it must have been started in a cell
	    }
	
	    // immediate click on "holder" means click on the right side of vertical scrollbar
	    if (next === instance.view.wt.wtTable.holder) {
	      var scrollbarWidth = (0, _element.getScrollbarWidth)();
	
	      if (document.elementFromPoint(eventX + scrollbarWidth, eventY) !== instance.view.wt.wtTable.holder || document.elementFromPoint(eventX, eventY + scrollbarWidth) !== instance.view.wt.wtTable.holder) {
	        return;
	      }
	    } else {
	      while (next !== document.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 === instance.rootElement) {
	          // click inside container
	          return;
	        }
	        next = next.parentNode;
	      }
	    }
	
	    // function did not return until here, we have an outside click!
	
	    var outsideClickDeselects = typeof that.settings.outsideClickDeselects === 'function' ? that.settings.outsideClickDeselects(originalTarget) : that.settings.outsideClickDeselects;
	
	    if (outsideClickDeselects) {
	      instance.deselectCell();
	    } else {
	      instance.destroyEditor();
	    }
	  });
	
	  this.eventManager.addEventListener(table, 'selectstart', function (event) {
	    if (that.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();
	  });
	
	  var clearTextSelection = function clearTextSelection() {
	    // http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript
	    if (window.getSelection) {
	      if (window.getSelection().empty) {
	        // Chrome
	        window.getSelection().empty();
	      } else if (window.getSelection().removeAllRanges) {
	        // Firefox
	        window.getSelection().removeAllRanges();
	      }
	    } else if (document.selection) {
	      // IE?
	      document.selection.empty();
	    }
	  };
	
	  var selections = [new _src.Selection({
	    className: 'current',
	    border: {
	      width: 2,
	      color: '#5292F7',
	      // style: 'solid', // not used
	      cornerVisible: function cornerVisible() {
	        return that.settings.fillHandle && !that.isCellEdited() && !instance.selection.isMultiple();
	      },
	      multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() {
	        return !that.isCellEdited() && !instance.selection.isMultiple();
	      }
	    }
	  }), new _src.Selection({
	    className: 'area',
	    border: {
	      width: 1,
	      color: '#89AFF9',
	      // style: 'solid', // not used
	      cornerVisible: function cornerVisible() {
	        return that.settings.fillHandle && !that.isCellEdited() && instance.selection.isMultiple();
	      },
	      multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() {
	        return !that.isCellEdited() && instance.selection.isMultiple();
	      }
	    }
	  }), new _src.Selection({
	    className: 'highlight',
	    highlightHeaderClassName: that.settings.currentHeaderClassName,
	    highlightRowClassName: that.settings.currentRowClassName,
	    highlightColumnClassName: that.settings.currentColClassName
	  }), new _src.Selection({
	    className: 'fill',
	    border: {
	      width: 1,
	      color: 'red'
	      // style: 'solid' // not used
	    }
	  })];
	  selections.current = selections[0];
	  selections.area = selections[1];
	  selections.highlight = selections[2];
	  selections.fill = selections[3];
	
	  var walkontableConfig = {
	    debug: function debug() {
	      return that.settings.debug;
	    },
	    externalRowCalculator: this.instance.getPlugin('autoRowSize') && this.instance.getPlugin('autoRowSize').isEnabled(),
	    table: table,
	    preventOverflow: function preventOverflow() {
	      return _this.settings.preventOverflow;
	    },
	    stretchH: function stretchH() {
	      return that.settings.stretchH;
	    },
	    data: instance.getDataAtCell,
	    totalRows: function totalRows() {
	      return instance.countRows();
	    },
	    totalColumns: function totalColumns() {
	      return instance.countCols();
	    },
	    fixedColumnsLeft: function fixedColumnsLeft() {
	      return that.settings.fixedColumnsLeft;
	    },
	    fixedRowsTop: function fixedRowsTop() {
	      return that.settings.fixedRowsTop;
	    },
	    fixedRowsBottom: function fixedRowsBottom() {
	      return that.settings.fixedRowsBottom;
	    },
	    minSpareRows: function minSpareRows() {
	      return that.settings.minSpareRows;
	    },
	    renderAllRows: that.settings.renderAllRows,
	    rowHeaders: function rowHeaders() {
	      var headerRenderers = [];
	
	      if (instance.hasRowHeaders()) {
	        headerRenderers.push(function (row, TH) {
	          that.appendRowHeader(row, TH);
	        });
	      }
	      instance.runHooks('afterGetRowHeaderRenderers', headerRenderers);
	
	      return headerRenderers;
	    },
	    columnHeaders: function columnHeaders() {
	      var headerRenderers = [];
	
	      if (instance.hasColHeaders()) {
	        headerRenderers.push(function (column, TH) {
	          that.appendColHeader(column, TH);
	        });
	      }
	      instance.runHooks('afterGetColumnHeaderRenderers', headerRenderers);
	
	      return headerRenderers;
	    },
	    columnWidth: instance.getColWidth,
	    rowHeight: instance.getRowHeight,
	    cellRenderer: function cellRenderer(row, col, TD) {
	      var cellProperties = that.instance.getCellMeta(row, col);
	      var prop = that.instance.colToProp(col);
	      var value = that.instance.getDataAtRowProp(row, prop);
	
	      if (that.instance.hasHook('beforeValueRender')) {
	        value = that.instance.runHooks('beforeValueRender', value);
	      }
	
	      that.instance.runHooks('beforeRenderer', TD, row, col, prop, value, cellProperties);
	      that.instance.getCellRenderer(cellProperties)(that.instance, TD, row, col, prop, value, cellProperties);
	      that.instance.runHooks('afterRenderer', TD, row, col, prop, value, cellProperties);
	    },
	    selections: selections,
	    hideBorderOnMouseDownOver: function hideBorderOnMouseDownOver() {
	      return that.settings.fragmentSelection;
	    },
	    onCellMouseDown: function onCellMouseDown(event, coords, TD, wt) {
	      var blockCalculations = {
	        row: false,
	        column: false,
	        cells: false
	      };
	
	      instance.listen();
	
	      that.activeWt = wt;
	      isMouseDown = true;
	
	      instance.runHooks('beforeOnCellMouseDown', event, coords, TD, blockCalculations);
	
	      if ((0, _event.isImmediatePropagationStopped)(event)) {
	        return;
	      }
	
	      var actualSelection = instance.getSelectedRange();
	      var selection = instance.selection;
	      var selectedHeader = selection.selectedHeader;
	
	      if (event.shiftKey && actualSelection) {
	        if (coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) {
	          selection.setSelectedHeaders(false, false);
	          selection.setRangeEnd(coords);
	        } else if ((selectedHeader.cols || selectedHeader.rows) && coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) {
	          selection.setSelectedHeaders(false, false);
	          selection.setRangeEnd(new _src.CellCoords(coords.row, coords.col));
	        } else if (selectedHeader.cols && coords.row < 0 && !blockCalculations.column) {
	          selection.setRangeEnd(new _src.CellCoords(actualSelection.to.row, coords.col));
	        } else if (selectedHeader.rows && coords.col < 0 && !blockCalculations.row) {
	          selection.setRangeEnd(new _src.CellCoords(coords.row, actualSelection.to.col));
	        } else if ((!selectedHeader.cols && !selectedHeader.rows && coords.col < 0 || selectedHeader.cols && coords.col < 0) && !blockCalculations.row) {
	          selection.setSelectedHeaders(true, false);
	          selection.setRangeStartOnly(new _src.CellCoords(actualSelection.from.row, 0));
	          selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1));
	        } else if ((!selectedHeader.cols && !selectedHeader.rows && coords.row < 0 || selectedHeader.rows && coords.row < 0) && !blockCalculations.column) {
	          selection.setSelectedHeaders(false, true);
	          selection.setRangeStartOnly(new _src.CellCoords(0, actualSelection.from.col));
	          selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col));
	        }
	      } else {
	        var doNewSelection = true;
	
	        if (actualSelection) {
	          var from = actualSelection.from,
	              to = actualSelection.to;
	
	          var coordsNotInSelection = !selection.inInSelection(coords);
	
	          if (coords.row < 0 && selectedHeader.cols) {
	            var start = Math.min(from.col, to.col);
	            var end = Math.max(from.col, to.col);
	
	            doNewSelection = coords.col < start || coords.col > end;
	          } else if (coords.col < 0 && selectedHeader.rows) {
	            var _start = Math.min(from.row, to.row);
	            var _end = Math.max(from.row, to.row);
	
	            doNewSelection = coords.row < _start || coords.row > _end;
	          } else {
	            doNewSelection = coordsNotInSelection;
	          }
	        }
	
	        var rightClick = (0, _event.isRightClick)(event);
	        var leftClick = (0, _event.isLeftClick)(event) || event.type === 'touchstart';
	
	        // clicked row header and when some column was selected
	        if (coords.row < 0 && coords.col >= 0 && !blockCalculations.column) {
	          selection.setSelectedHeaders(false, true);
	
	          if (leftClick || rightClick && doNewSelection) {
	            selection.setRangeStartOnly(new _src.CellCoords(0, coords.col));
	            selection.setRangeEnd(new _src.CellCoords(Math.max(instance.countRows() - 1, 0), coords.col), false);
	          }
	
	          // clicked column header and when some row was selected
	        } else if (coords.col < 0 && coords.row >= 0 && !blockCalculations.row) {
	          selection.setSelectedHeaders(true, false);
	
	          if (leftClick || rightClick && doNewSelection) {
	            selection.setRangeStartOnly(new _src.CellCoords(coords.row, 0));
	            selection.setRangeEnd(new _src.CellCoords(coords.row, Math.max(instance.countCols() - 1, 0)), false);
	          }
	        } else if (coords.col >= 0 && coords.row >= 0 && !blockCalculations.cells) {
	          if (leftClick || rightClick && doNewSelection) {
	            selection.setSelectedHeaders(false, false);
	            selection.setRangeStart(coords);
	          }
	        } else if (coords.col < 0 && coords.row < 0) {
	          coords.row = 0;
	          coords.col = 0;
	
	          selection.setSelectedHeaders(false, false, true);
	          selection.setRangeStart(coords);
	        }
	      }
	
	      instance.runHooks('afterOnCellMouseDown', event, coords, TD);
	      that.activeWt = that.wt;
	    },
	    onCellMouseOut: function onCellMouseOut(event, coords, TD, wt) {
	      that.activeWt = wt;
	      instance.runHooks('beforeOnCellMouseOut', event, coords, TD);
	
	      if ((0, _event.isImmediatePropagationStopped)(event)) {
	        return;
	      }
	
	      instance.runHooks('afterOnCellMouseOut', event, coords, TD);
	      that.activeWt = that.wt;
	    },
	    onCellMouseOver: function onCellMouseOver(event, coords, TD, wt) {
	      var blockCalculations = {
	        row: false,
	        column: false,
	        cell: false
	      };
	
	      that.activeWt = wt;
	      instance.runHooks('beforeOnCellMouseOver', event, coords, TD, blockCalculations);
	
	      if ((0, _event.isImmediatePropagationStopped)(event)) {
	        return;
	      }
	
	      if (event.button === 0 && isMouseDown) {
	        if (coords.row >= 0 && coords.col >= 0) {
	          // is not a header
	          if (instance.selection.selectedHeader.cols && !blockCalculations.column) {
	            instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false);
	          } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) {
	            instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false);
	          } else if (!blockCalculations.cell) {
	            instance.selection.setRangeEnd(coords);
	          }
	        } else {
	          /* eslint-disable no-lonely-if */
	          if (instance.selection.selectedHeader.cols && !blockCalculations.column) {
	            instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false);
	          } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) {
	            instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false);
	          } else if (!blockCalculations.cell) {
	            instance.selection.setRangeEnd(coords);
	          }
	        }
	      }
	
	      instance.runHooks('afterOnCellMouseOver', event, coords, TD);
	      that.activeWt = that.wt;
	    },
	    onCellMouseUp: function onCellMouseUp(event, coords, TD, wt) {
	      that.activeWt = wt;
	      instance.runHooks('beforeOnCellMouseUp', event, coords, TD);
	
	      instance.runHooks('afterOnCellMouseUp', event, coords, TD);
	      that.activeWt = that.wt;
	    },
	    onCellCornerMouseDown: function onCellCornerMouseDown(event) {
	      event.preventDefault();
	      instance.runHooks('afterOnCellCornerMouseDown', event);
	    },
	    onCellCornerDblClick: function onCellCornerDblClick(event) {
	      event.preventDefault();
	      instance.runHooks('afterOnCellCornerDblClick', event);
	    },
	    beforeDraw: function beforeDraw(force, skipRender) {
	      that.beforeRender(force, skipRender);
	    },
	    onDraw: function onDraw(force) {
	      that.onDraw(force);
	    },
	    onScrollVertically: function onScrollVertically() {
	      instance.runHooks('afterScrollVertically');
	    },
	    onScrollHorizontally: function onScrollHorizontally() {
	      instance.runHooks('afterScrollHorizontally');
	    },
	    onBeforeDrawBorders: function onBeforeDrawBorders(corners, borderClassName) {
	      instance.runHooks('beforeDrawBorders', corners, borderClassName);
	    },
	    onBeforeTouchScroll: function onBeforeTouchScroll() {
	      instance.runHooks('beforeTouchScroll');
	    },
	    onAfterMomentumScroll: function onAfterMomentumScroll() {
	      instance.runHooks('afterMomentumScroll');
	    },
	    onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(stretchedWidth, column) {
	      return instance.runHooks('beforeStretchingColumnWidth', stretchedWidth, column);
	    },
	    onModifyRowHeaderWidth: function onModifyRowHeaderWidth(rowHeaderWidth) {
	      return instance.runHooks('modifyRowHeaderWidth', rowHeaderWidth);
	    },
	    viewportRowCalculatorOverride: function viewportRowCalculatorOverride(calc) {
	      var rows = instance.countRows();
	      var viewportOffset = that.settings.viewportRowRenderingOffset;
	
	      if (viewportOffset === 'auto' && that.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);
	      }
	      instance.runHooks('afterViewportRowCalculatorOverride', calc);
	    },
	    viewportColumnCalculatorOverride: function viewportColumnCalculatorOverride(calc) {
	      var cols = instance.countCols();
	      var viewportOffset = that.settings.viewportColumnRenderingOffset;
	
	      if (viewportOffset === 'auto' && that.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);
	      }
	      instance.runHooks('afterViewportColumnCalculatorOverride', calc);
	    },
	    rowHeaderWidth: function rowHeaderWidth() {
	      return that.settings.rowHeaderWidth;
	    },
	    columnHeaderHeight: function columnHeaderHeight() {
	      var columnHeaderHeight = instance.runHooks('modifyColumnHeaderHeight');
	      return that.settings.columnHeaderHeight || columnHeaderHeight;
	    }
	  };
	
	  instance.runHooks('beforeInitWalkontable', walkontableConfig);
	
	  this.wt = new _src2.default(walkontableConfig);
	  this.activeWt = this.wt;
	
	  if (!(0, _browser.isChrome)() && !(0, _browser.isSafari)()) {
	    this.eventManager.addEventListener(instance.rootElement, 'wheel', function (event) {
	      event.preventDefault();
	
	      var lineHeight = parseInt((0, _element.getComputedStyle)(document.body)['font-size'], 10);
	      var holder = that.wt.wtOverlays.scrollableElement;
	
	      var deltaY = event.wheelDeltaY || event.deltaY;
	      var deltaX = event.wheelDeltaX || event.deltaX;
	
	      switch (event.deltaMode) {
	        case 0:
	          holder.scrollLeft += deltaX;
	          holder.scrollTop += deltaY;
	          break;
	
	        case 1:
	          holder.scrollLeft += deltaX * lineHeight;
	          holder.scrollTop += deltaY * lineHeight;
	          break;
	
	        default:
	          break;
	      }
	    });
	  }
	
	  this.eventManager.addEventListener(that.wt.wtTable.spreader, 'mousedown', function (event) {
	    // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
	    if (event.target === that.wt.wtTable.spreader && event.which === 3) {
	      (0, _event.stopPropagation)(event);
	    }
	  });
	
	  this.eventManager.addEventListener(that.wt.wtTable.spreader, 'contextmenu', function (event) {
	    // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
	    if (event.target === that.wt.wtTable.spreader && event.which === 3) {
	      (0, _event.stopPropagation)(event);
	    }
	  });
	
	  this.eventManager.addEventListener(document.documentElement, 'click', function () {
	    if (that.settings.observeDOMVisibility) {
	      if (that.wt.drawInterrupted) {
	        that.instance.forceFullRender = true;
	        that.render();
	      }
	    }
	  });
	}
	
	TableView.prototype.isTextSelectionAllowed = function (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;
	};
	
	/**
	 * Check if selected only one cell.
	 *
	 * @returns {Boolean}
	 */
	TableView.prototype.isSelectedOnlyCell = function () {
	  var _ref = this.instance.getSelected() || [],
	      _ref2 = _slicedToArray(_ref, 4),
	      row = _ref2[0],
	      col = _ref2[1],
	      rowEnd = _ref2[2],
	      colEnd = _ref2[3];
	
	  return row !== void 0 && row === rowEnd && col === colEnd;
	};
	
	TableView.prototype.isCellEdited = function () {
	  var activeEditor = this.instance.getActiveEditor();
	
	  return activeEditor && activeEditor.isOpened();
	};
	
	TableView.prototype.beforeRender = function (force, skipRender) {
	  if (force) {
	    // this.instance.forceFullRender = did Handsontable request full render?
	    this.instance.runHooks('beforeRender', this.instance.forceFullRender, skipRender);
	  }
	};
	
	TableView.prototype.onDraw = function (force) {
	  if (force) {
	    // this.instance.forceFullRender = did Handsontable request full render?
	    this.instance.runHooks('afterRender', this.instance.forceFullRender);
	  }
	};
	
	TableView.prototype.render = function () {
	  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
	 */
	TableView.prototype.getCellAtCoords = function (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 selection.
	 *
	 * @param {CellCoords} coords
	 */
	TableView.prototype.scrollViewport = function (coords) {
	  this.wt.scrollViewport(coords);
	};
	
	/**
	 * Append row header to a TH element
	 * @param row
	 * @param TH
	 */
	TableView.prototype.appendRowHeader = function (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 div = document.createElement('div');
	    var span = document.createElement('span');
	
	    div.className = 'relative';
	    span.className = 'rowHeader';
	    this.updateCellHeader(span, row, this.instance.getRowHeader);
	
	    div.appendChild(span);
	    TH.appendChild(div);
	  }
	
	  this.instance.runHooks('afterGetRowHeader', row, TH);
	};
	
	/**
	 * Append column header to a TH element
	 * @param col
	 * @param TH
	 */
	TableView.prototype.appendColHeader = function (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 div = document.createElement('div');
	    var span = document.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);
	};
	
	/**
	 * Update 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
	 */
	TableView.prototype.updateCellHeader = function (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');
	  }
	};
	
	/**
	 * Given a element's left position relative to the viewport, returns maximum element width until the right
	 * edge of the viewport (before scrollbar)
	 *
	 * @param {Number} leftOffset
	 * @return {Number}
	 */
	TableView.prototype.maximumVisibleElementWidth = function (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)
	 *
	 * @param {Number} topOffset
	 * @return {Number}
	 */
	TableView.prototype.maximumVisibleElementHeight = function (topOffset) {
	  var workspaceHeight = this.wt.wtViewport.getWorkspaceHeight();
	  var maxHeight = workspaceHeight - topOffset;
	  return maxHeight > 0 ? maxHeight : 0;
	};
	
	TableView.prototype.mainViewIsActive = function () {
	  return this.wt === this.activeWt;
	};
	
	TableView.prototype.destroy = function () {
	  this.wt.destroy();
	  this.eventManager.destroy();
	};
	
	exports.default = TableView;
	
	/***/ }),
	/* 245 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _object = __webpack_require__(1);
	
	var _array = __webpack_require__(2);
	
	var _number = __webpack_require__(6);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class DataSource
	 * @private
	 */
	var DataSource = function () {
	  function DataSource(hotInstance) {
	    var dataSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
	
	    _classCallCheck(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}
	   */
	
	
	  _createClass(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);
	
	        if (typeof property === 'string') {
	          row = (0, _object.getProperty)(row, property);
	        } else {
	          row = row[property];
	        }
	        result.push(row);
	      });
	
	      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 = void 0;
	
	        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;
	}();
	
	exports.default = DataSource;
	
	/***/ }),
	/* 246 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = jQueryWrapper;
	function jQueryWrapper(Handsontable) {
	  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;
	    }
	
	    // Action case
	    var args = [];
	    var output = void 0;
	
	    if (arguments.length > 1) {
	      for (var i = 1, ilen = arguments.length; i < ilen; i++) {
	        args.push(arguments[i]);
	      }
	    }
	
	    if (instance) {
	      if (typeof instance[action] !== 'undefined') {
	        output = instance[action].apply(instance, args);
	
	        if (action === 'destroy') {
	          $this.removeData();
	        }
	      } else {
	        throw new Error('Handsontable do not provide action: ' + action);
	      }
	    }
	
	    return output;
	  };
	};
	
	/***/ }),
	/* 247 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.Base = exports.UndoRedo = exports.TouchScroll = exports.Search = exports.PersistentState = exports.ObserveChanges = exports.MultipleSelectionHandles = exports.MergeCells = exports.ManualRowResize = exports.ManualRowMove = exports.ManualColumnResize = exports.ManualColumnMove = exports.ManualColumnFreeze = exports.DragToScroll = exports.CustomBorders = exports.CopyPaste = exports.ContextMenu = exports.Comments = exports.ColumnSorting = exports.AutoRowSize = exports.AutoFill = exports.AutoColumnSize = undefined;
	
	var _autoColumnSize = __webpack_require__(248);
	
	var _autoColumnSize2 = _interopRequireDefault(_autoColumnSize);
	
	var _autofill = __webpack_require__(249);
	
	var _autofill2 = _interopRequireDefault(_autofill);
	
	var _autoRowSize = __webpack_require__(251);
	
	var _autoRowSize2 = _interopRequireDefault(_autoRowSize);
	
	var _columnSorting = __webpack_require__(252);
	
	var _columnSorting2 = _interopRequireDefault(_columnSorting);
	
	var _comments = __webpack_require__(255);
	
	var _comments2 = _interopRequireDefault(_comments);
	
	var _contextMenu = __webpack_require__(259);
	
	var _contextMenu2 = _interopRequireDefault(_contextMenu);
	
	var _copyPaste = __webpack_require__(276);
	
	var _copyPaste2 = _interopRequireDefault(_copyPaste);
	
	var _customBorders = __webpack_require__(283);
	
	var _customBorders2 = _interopRequireDefault(_customBorders);
	
	var _dragToScroll = __webpack_require__(284);
	
	var _dragToScroll2 = _interopRequireDefault(_dragToScroll);
	
	var _manualColumnFreeze = __webpack_require__(285);
	
	var _manualColumnFreeze2 = _interopRequireDefault(_manualColumnFreeze);
	
	var _manualColumnMove = __webpack_require__(289);
	
	var _manualColumnMove2 = _interopRequireDefault(_manualColumnMove);
	
	var _manualColumnResize = __webpack_require__(294);
	
	var _manualColumnResize2 = _interopRequireDefault(_manualColumnResize);
	
	var _manualRowMove = __webpack_require__(295);
	
	var _manualRowMove2 = _interopRequireDefault(_manualRowMove);
	
	var _manualRowResize = __webpack_require__(300);
	
	var _manualRowResize2 = _interopRequireDefault(_manualRowResize);
	
	var _mergeCells = __webpack_require__(301);
	
	var _mergeCells2 = _interopRequireDefault(_mergeCells);
	
	var _multipleSelectionHandles = __webpack_require__(302);
	
	var _multipleSelectionHandles2 = _interopRequireDefault(_multipleSelectionHandles);
	
	var _observeChanges = __webpack_require__(303);
	
	var _observeChanges2 = _interopRequireDefault(_observeChanges);
	
	var _persistentState = __webpack_require__(306);
	
	var _persistentState2 = _interopRequireDefault(_persistentState);
	
	var _search = __webpack_require__(307);
	
	var _search2 = _interopRequireDefault(_search);
	
	var _touchScroll = __webpack_require__(308);
	
	var _touchScroll2 = _interopRequireDefault(_touchScroll);
	
	var _undoRedo = __webpack_require__(309);
	
	var _undoRedo2 = _interopRequireDefault(_undoRedo);
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	exports.AutoColumnSize = _autoColumnSize2.default;
	exports.AutoFill = _autofill2.default;
	exports.AutoRowSize = _autoRowSize2.default;
	exports.ColumnSorting = _columnSorting2.default;
	exports.Comments = _comments2.default;
	exports.ContextMenu = _contextMenu2.default;
	exports.CopyPaste = _copyPaste2.default;
	exports.CustomBorders = _customBorders2.default;
	exports.DragToScroll = _dragToScroll2.default;
	exports.ManualColumnFreeze = _manualColumnFreeze2.default;
	exports.ManualColumnMove = _manualColumnMove2.default;
	exports.ManualColumnResize = _manualColumnResize2.default;
	exports.ManualRowMove = _manualRowMove2.default;
	exports.ManualRowResize = _manualRowResize2.default;
	exports.MergeCells = _mergeCells2.default;
	exports.MultipleSelectionHandles = _multipleSelectionHandles2.default;
	exports.ObserveChanges = _observeChanges2.default;
	exports.PersistentState = _persistentState2.default;
	exports.Search = _search2.default;
	exports.TouchScroll = _touchScroll2.default;
	exports.UndoRedo = _undoRedo2.default;
	exports.Base = _base2.default;
	
	/***/ }),
	/* 248 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _slicedToArray = function () { function sliceIterator(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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _array = __webpack_require__(2);
	
	var _feature = __webpack_require__(34);
	
	var _element = __webpack_require__(0);
	
	var _ghostTable = __webpack_require__(85);
	
	var _ghostTable2 = _interopRequireDefault(_ghostTable);
	
	var _object = __webpack_require__(1);
	
	var _number = __webpack_require__(6);
	
	var _plugins = __webpack_require__(5);
	
	var _samplesGenerator = __webpack_require__(175);
	
	var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator);
	
	var _string = __webpack_require__(32);
	
	var _src = __webpack_require__(12);
	
	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; }
	
	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
	 * ...
	 * var hot = new Handsontable(document.getElementById('example'), {
	 *   date: getData(),
	 *   autoColumnSize: true
	 * });
	 * // Access to plugin instance:
	 * var plugin = hot.getPlugin('autoColumnSize');
	 *
	 * plugin.getColumnWidth(4);
	 *
	 * if (plugin.isEnabled()) {
	 *   // code...
	 * }
	 * ...
	 * ```
	 */
	
	var AutoColumnSize = function (_BasePlugin) {
	  _inherits(AutoColumnSize, _BasePlugin);
	
	  _createClass(AutoColumnSize, null, [{
	    key: 'CALCULATION_STEP',
	    get: function get() {
	      return 50;
	    }
	  }, {
	    key: 'SYNC_CALCULATION_LIMIT',
	    get: function get() {
	      return 50;
	    }
	  }]);
	
	  function AutoColumnSize(hotInstance) {
	    _classCallCheck(this, AutoColumnSize);
	
	    var _this = _possibleConstructorReturn(this, (AutoColumnSize.__proto__ || Object.getPrototypeOf(AutoColumnSize)).call(this, hotInstance));
	
	    privatePool.set(_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 {Array}
	     */
	    _this.widths = [];
	    /**
	     * Instance of {@link GhostTable} for rows and columns size calculations.
	     *
	     * @type {GhostTable}
	     */
	    _this.ghostTable = new _ghostTable2.default(_this.hot);
	    /**
	     * Instance of {@link SamplesGenerator} for generating samples necessary for columns width calculations.
	     *
	     * @type {SamplesGenerator}
	     */
	    _this.samplesGenerator = new _samplesGenerator2.default(function (row, col) {
	      return _this.hot.getDataAtCell(row, col);
	    });
	    /**
	     * `true` only if the first calculation was performed
	     *
	     * @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;
	  }
	
	  /**
	   * Check if the plugin is enabled in the handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(AutoColumnSize, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return this.hot.getSettings().autoColumnSize !== false && !this.hot.getSettings().colWidths;
	    }
	
	    /**
	     * Enable plugin 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) {
	        this.ghostTable.setSetting('useHeaders', setting.useHeaders);
	      }
	
	      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();
	      });
	      _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Update plugin state.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      var changedColumns = this.findColumnsWhereHeaderWasChanged();
	
	      if (changedColumns.length) {
	        this.clearCache(changedColumns);
	      }
	      _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Calculate a columns width.
	     *
	     * @param {Number|Object} colRange Column range object.
	     * @param {Number|Object} rowRange Row range object.
	     * @param {Boolean} [force=false] If `true` force calculate width even when value was cached earlier.
	     */
	
	  }, {
	    key: 'calculateColumnsWidth',
	    value: function calculateColumnsWidth() {
	      var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countCols() - 1 };
	
	      var _this3 = this;
	
	      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;
	
	      if (typeof colRange === 'number') {
	        colRange = { from: colRange, to: colRange };
	      }
	      if (typeof rowRange === 'number') {
	        rowRange = { from: rowRange, to: rowRange };
	      }
	
	      (0, _number.rangeEach)(colRange.from, colRange.to, function (col) {
	        if (force || _this3.widths[col] === void 0 && !_this3.hot._getColWidthFromSettings(col)) {
	          var samples = _this3.samplesGenerator.generateColumnSamples(col, rowRange);
	
	          samples.forEach(function (sample, col) {
	            return _this3.ghostTable.addColumn(col, sample);
	          });
	        }
	      });
	
	      if (this.ghostTable.columns.length) {
	        this.ghostTable.getWidths(function (col, width) {
	          _this3.widths[col] = width;
	        });
	        this.ghostTable.clean();
	      }
	    }
	
	    /**
	     * Calculate all columns width.
	     *
	     * @param {Object|Number} rowRange Row range object.
	     */
	
	  }, {
	    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(true);
	          // tmp
	          if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) {
	            _this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw();
	          }
	        }
	      };
	      // sync
	      if (this.firstCalculation && this.getSyncCalculationLimit()) {
	        this.calculateColumnsWidth({ from: 0, to: this.getSyncCalculationLimit() }, rowRange);
	        this.firstCalculation = false;
	        current = this.getSyncCalculationLimit() + 1;
	      }
	      // async
	      if (current < length) {
	        loop();
	      } else {
	        this.inProgress = false;
	      }
	    }
	
	    /**
	     * Set 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);
	      }
	    }
	
	    /**
	     * Recalculate 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();
	      }
	    }
	
	    /**
	     * Get value which tells how many columns should be calculated synchronously. Rest of the columns will be calculated asynchronously.
	     *
	     * @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);
	    }
	
	    /**
	     * Get the calculated column width.
	     *
	     * @param {Number} col 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(col) {
	      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[col];
	
	        if (keepMinimum && typeof width === 'number') {
	          width = Math.max(width, _src.ViewportColumnsCalculator.DEFAULT_WIDTH);
	        }
	      }
	
	      return width;
	    }
	
	    /**
	     * Get the first visible column.
	     *
	     * @returns {Number} Returns column index or -1 if table is not rendered.
	     */
	
	  }, {
	    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;
	    }
	
	    /**
	     * Get 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.
	     *
	     * @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;
	    }
	
	    /**
	     * Clear 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 {Array} [columns=[]] List of column indexes (physical 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;
	      }
	    }
	
	    /**
	     * Check 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();
	
	      // Keep last column widths unchanged for situation when all rows was deleted or trimmed (pro #6)
	      if (!rowsCount) {
	        return;
	      }
	
	      this.calculateColumnsWidth({ from: this.getFirstVisibleColumn(), to: this.getLastVisibleColumn() }, 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 (_ref) {
	        var _ref2 = _slicedToArray(_ref, 2),
	            row = _ref2[0],
	            column = _ref2[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) {
	      if (isDblClick) {
	        this.calculateColumnsWidth(col, void 0, true);
	        size = this.getColumnWidth(col, void 0, false);
	      }
	
	      return size;
	    }
	
	    /**
	     * On after Handsontable init fill plugin with all necessary values.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'onAfterInit',
	    value: function onAfterInit() {
	      privatePool.get(this).cachedColumnHeaders = this.hot.getColHeader();
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      this.ghostTable.clean();
	      _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return AutoColumnSize;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('autoColumnSize', AutoColumnSize);
	
	exports.default = AutoColumnSize;
	
	/***/ }),
	/* 249 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _element = __webpack_require__(0);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _plugins = __webpack_require__(5);
	
	var _src = __webpack_require__(12);
	
	var _utils = __webpack_require__(250);
	
	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; }
	
	_pluginHooks2.default.getSingleton().register('modifyAutofillRange');
	_pluginHooks2.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 = function (_BasePlugin) {
	  _inherits(Autofill, _BasePlugin);
	
	  function Autofill(hotInstance) {
	    _classCallCheck(this, Autofill);
	
	    /**
	     * Event manager
	     *
	     * @type {EventManager}
	     */
	    var _this = _possibleConstructorReturn(this, (Autofill.__proto__ || Object.getPrototypeOf(Autofill)).call(this, hotInstance));
	
	    _this.eventManager = new _eventManager2.default(_this);
	    /**
	     * Specifies if adding new row started.
	     *
	     * @type {Boolean}
	     */
	    _this.addingStarted = false;
	    /**
	     * Specifies if there was mouse down on the cell corner.
	     *
	     * @type {Boolean}
	     */
	    _this.mouseDownOnCellCorner = false;
	    /**
	     * Specifies if mouse was dragged outside Handsontable.
	     *
	     * @type {Boolean}
	     */
	    _this.mouseDragOutside = false;
	    /**
	     * Specifies how many cell levels were dragged using the handle.
	     *
	     * @type {Boolean}
	     */
	    _this.handleDraggedCells = 0;
	    /**
	     * Specifies allowed directions of drag.
	     *
	     * @type {Array}
	     */
	    _this.directions = [];
	    /**
	     * Specifies if can insert new rows if needed.
	     *
	     * @type {Boolean}
	     */
	    _this.autoInsertRow = false;
	    return _this;
	  }
	
	  /**
	   * Check if the plugin is enabled in the Handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(Autofill, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return this.hot.getSettings().fillHandle;
	    }
	
	    /**
	     * Enable plugin 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, TD) {
	        return _this2.onBeforeCellMouseOver(coords);
	      });
	
	      _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Update plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      this.disablePlugin();
	      this.enablePlugin();
	      _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      this.clearMappedSettings();
	      _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Get selection data
	     *
	     * @private
	     * @returns {Array} Array with the data.
	     */
	
	  }, {
	    key: 'getSelectionData',
	    value: function getSelectionData() {
	      var selRange = {
	        from: this.hot.getSelectedRange().from,
	        to: this.hot.getSelectedRange().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.
	     */
	
	  }, {
	    key: 'fillIn',
	    value: function fillIn() {
	      if (this.hot.view.wt.selections.fill.isEmpty()) {
	        return false;
	      }
	
	      var cornersOfSelectionAndDragAreas = this.hot.view.wt.selections.fill.getCorners();
	
	      this.resetSelectionOfDraggedArea();
	
	      var cornersOfSelectedCells = this.getCornersOfSelectedCells();
	
	      var _getDragDirectionAndR = (0, _utils.getDragDirectionAndRange)(cornersOfSelectedCells, cornersOfSelectionAndDragAreas),
	          directionOfDrag = _getDragDirectionAndR.directionOfDrag,
	          startOfDragCoords = _getDragDirectionAndR.startOfDragCoords,
	          endOfDragCoords = _getDragDirectionAndR.endOfDragCoords;
	
	      this.hot.runHooks('modifyAutofillRange', cornersOfSelectedCells, cornersOfSelectionAndDragAreas);
	
	      if (startOfDragCoords && startOfDragCoords.row > -1 && startOfDragCoords.col > -1) {
	        var selectionData = this.getSelectionData();
	        var deltas = (0, _utils.getDeltas)(startOfDragCoords, endOfDragCoords, selectionData, directionOfDrag);
	        var fillData = selectionData;
	
	        this.hot.runHooks('beforeAutofill', startOfDragCoords, endOfDragCoords, 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, this.pluginName + '.fill', null, directionOfDrag, deltas);
	
	        this.setSelection(cornersOfSelectionAndDragAreas);
	      } else {
	        // reset to avoid some range bug
	        this.hot.selection.refreshBorders();
	      }
	
	      return true;
	    }
	
	    /**
	     * Reduce 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;
	    }
	
	    /**
	     * Get 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.getSelectedRange().getTopLeftCorner();
	      var bottomRightCorner = this.hot.getSelectedRange().getBottomRightCorner();
	      var coords = void 0;
	
	      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, _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.view.wt.selections.fill.cellRange && this.addingStarted === false && this.autoInsertRow) {
	        var cornersOfSelectedCells = this.hot.getSelected();
	        var cornersOfSelectedDragArea = this.hot.view.wt.selections.fill.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.view.wt.selections.area.getCorners();
	      }
	      return this.hot.view.wt.selections.current.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 = void 0;
	
	      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;
	    }
	
	    /**
	     * Add 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.view.wt.selections.fill.clear();
	      this.hot.view.wt.selections.fill.add(new _src.CellCoords(selectStartArea[0], selectStartArea[1]));
	      this.hot.view.wt.selections.fill.add(new _src.CellCoords(rowIndex, selectStartArea[3]));
	    }
	
	    /**
	     * Set selection based on passed corners.
	     *
	     * @private
	     * @param {Array} cornersOfArea
	     */
	
	  }, {
	    key: 'setSelection',
	    value: function setSelection(cornersOfArea) {
	      this.hot.selection.setRangeStart(new _src.CellCoords(cornersOfArea[0], cornersOfArea[1]));
	      this.hot.selection.setRangeEnd(new _src.CellCoords(cornersOfArea[2], cornersOfArea[3]));
	    }
	
	    /**
	     * 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) {
	        return false;
	      }
	      this.addSelectionFromStartAreaToSpecificRowIndex(cornersOfSelectedCells, lastFilledInRowIndex);
	
	      return true;
	    }
	
	    /**
	     * Reset selection of dragged area.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'resetSelectionOfDraggedArea',
	    value: function resetSelectionOfDraggedArea() {
	      this.handleDraggedCells = 0;
	
	      this.hot.view.wt.selections.fill.clear();
	    }
	
	    /**
	     * Redraw borders.
	     *
	     * @private
	     * @param {CellCoords} coords `CellCoords` coord object.
	     */
	
	  }, {
	    key: 'redrawBorders',
	    value: function redrawBorders(coords) {
	      this.hot.view.wt.selections.fill.clear();
	      this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().from);
	      this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().to);
	      this.hot.view.wt.selections.fill.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 tableBottom = (0, _element.offset)(this.hot.table).top - (window.pageYOffset || document.documentElement.scrollTop) + (0, _element.outerHeight)(this.hot.table);
	      var tableRight = (0, _element.offset)(this.hot.table).left - (window.pageXOffset || document.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;
	
	      this.eventManager.addEventListener(document.documentElement, 'mouseup', function () {
	        return _this4.onMouseUp();
	      });
	      this.eventManager.addEventListener(document.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++;
	
	        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();
	      }
	    }
	
	    /**
	     * Clear 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;
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return Autofill;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('autofill', Autofill);
	
	exports.default = Autofill;
	
	/***/ }),
	/* 250 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.DIRECTIONS = undefined;
	exports.getDeltas = getDeltas;
	exports.getDragDirectionAndRange = getDragDirectionAndRange;
	exports.getMappedFillHandleSetting = getMappedFillHandleSetting;
	
	var _object = __webpack_require__(1);
	
	var _mixed = __webpack_require__(22);
	
	var _src = __webpack_require__(12);
	
	var DIRECTIONS = exports.DIRECTIONS = {
	  horizontal: 'horizontal',
	  vertical: 'vertical'
	};
	
	/**
	 * Get deltas array.
	 *
	 * @param {CellCoords} start
	 * @param {CellCoords} end
	 * @param {Array} data
	 * @param {String} direction
	 * @returns {Array}
	 */
	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 = void 0,
	      endOfDragCoords = void 0,
	      directionOfDrag = void 0;
	
	  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[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;
	}
	
	/***/ }),
	/* 251 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _array = __webpack_require__(2);
	
	var _feature = __webpack_require__(34);
	
	var _element = __webpack_require__(0);
	
	var _ghostTable = __webpack_require__(85);
	
	var _ghostTable2 = _interopRequireDefault(_ghostTable);
	
	var _object = __webpack_require__(1);
	
	var _number = __webpack_require__(6);
	
	var _plugins = __webpack_require__(5);
	
	var _samplesGenerator = __webpack_require__(175);
	
	var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator);
	
	var _string = __webpack_require__(32);
	
	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; }
	
	/**
	 * @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%'},
	 * ...
	 * ```
	 *
	 * 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
	 * ...
	 * var hot = new Handsontable(document.getElementById('example'), {
	 *   date: getData(),
	 *   autoRowSize: true
	 * });
	 * // Access to plugin instance:
	 * var plugin = hot.getPlugin('autoRowSize');
	 *
	 * plugin.getRowHeight(4);
	 *
	 * if (plugin.isEnabled()) {
	 *   // code...
	 * }
	 * ...
	 * ```
	 */
	var AutoRowSize = function (_BasePlugin) {
	  _inherits(AutoRowSize, _BasePlugin);
	
	  _createClass(AutoRowSize, null, [{
	    key: 'CALCULATION_STEP',
	    get: function get() {
	      return 50;
	    }
	  }, {
	    key: 'SYNC_CALCULATION_LIMIT',
	    get: function get() {
	      return 500;
	    }
	  }]);
	
	  function AutoRowSize(hotInstance) {
	    _classCallCheck(this, AutoRowSize);
	
	    /**
	     * Cached rows heights.
	     *
	     * @type {Array}
	     */
	    var _this = _possibleConstructorReturn(this, (AutoRowSize.__proto__ || Object.getPrototypeOf(AutoRowSize)).call(this, hotInstance));
	
	    _this.heights = [];
	    /**
	     * Instance of {@link GhostTable} for rows and columns size calculations.
	     *
	     * @type {GhostTable}
	     */
	    _this.ghostTable = new _ghostTable2.default(_this.hot);
	    /**
	     * Instance of {@link SamplesGenerator} for generating samples necessary for rows height calculations.
	     *
	     * @type {SamplesGenerator}
	     */
	    _this.samplesGenerator = new _samplesGenerator2.default(function (row, col) {
	      if (row >= 0) {
	        return _this.hot.getDataAtCell(row, col);
	      } else if (row === -1) {
	        return _this.hot.getColHeader(col);
	      }
	      return null;
	    });
	    /**
	     * `true` if only the first calculation was performed.
	     *
	     * @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;
	  }
	
	  /**
	   * Check if the plugin is enabled in the Handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(AutoRowSize, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return this.hot.getSettings().autoRowSize === true || (0, _object.isObject)(this.hot.getSettings().autoRowSize);
	    }
	
	    /**
	     * Enable plugin 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();
	      });
	      _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Calculate a given rows height.
	     *
	     * @param {Number|Object} rowRange Row range object.
	     * @param {Number|Object} colRange Column range object.
	     * @param {Boolean} [force=false] If `true` force calculate height even when value was cached earlier.
	     */
	
	  }, {
	    key: 'calculateRowsHeight',
	    value: function calculateRowsHeight() {
	      var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countRows() - 1 };
	
	      var _this3 = this;
	
	      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;
	
	      if (typeof rowRange === 'number') {
	        rowRange = { from: rowRange, to: rowRange };
	      }
	      if (typeof colRange === 'number') {
	        colRange = { from: colRange, to: colRange };
	      }
	
	      if (this.hot.getColHeader(0) !== null) {
	        var samples = this.samplesGenerator.generateRowSamples(-1, colRange);
	
	        this.ghostTable.addColumnHeadersRow(samples.get(-1));
	      }
	
	      (0, _number.rangeEach)(rowRange.from, rowRange.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, colRange);
	
	          _samples.forEach(function (sample, row) {
	            _this3.ghostTable.addRow(row, sample);
	          });
	        }
	      });
	      if (this.ghostTable.rows.length) {
	        this.ghostTable.getHeights(function (row, height) {
	          _this3.heights[row] = height;
	        });
	        this.ghostTable.clean();
	      }
	    }
	
	    /**
	     * Calculate the height of all the rows.
	     *
	     * @param {Object|Number} colRange Column range object.
	     */
	
	  }, {
	    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();
	          }
	        }
	      };
	      // sync
	      if (this.firstCalculation && this.getSyncCalculationLimit()) {
	        this.calculateRowsHeight({ from: 0, to: this.getSyncCalculationLimit() }, colRange);
	        this.firstCalculation = false;
	        current = this.getSyncCalculationLimit() + 1;
	      }
	      // async
	      if (current < length) {
	        loop();
	      } else {
	        this.inProgress = false;
	        this.hot.view.wt.wtOverlays.adjustElementsSize(false);
	      }
	    }
	
	    /**
	     * Set 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);
	      }
	    }
	
	    /**
	     * Recalculate 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();
	      }
	    }
	
	    /**
	     * Get value which tells how much rows will be calculated synchronously. Rest rows will be calculated asynchronously.
	     *
	     * @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);
	    }
	
	    /**
	     * Get the calculated row height.
	     *
	     * @param {Number} row Visual row index.
	     * @param {Number} [defaultHeight] Default row height. It will be pick 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} Returns row index or -1 if table is not rendered.
	     */
	
	  }, {
	    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;
	    }
	
	    /**
	     * Get 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;
	    }
	
	    /**
	     * Clear cached heights.
	     */
	
	  }, {
	    key: 'clearCache',
	    value: function clearCache() {
	      this.heights.length = 0;
	      this.heights[-1] = void 0;
	    }
	
	    /**
	     * Clear cache by range.
	     *
	     * @param {Object|Number} range Row range object.
	     */
	
	  }, {
	    key: 'clearCacheByRange',
	    value: function clearCacheByRange(range) {
	      var _this5 = this;
	
	      if (typeof range === 'number') {
	        range = { from: range, to: range };
	      }
	      (0, _number.rangeEach)(Math.min(range.from, range.to), Math.max(range.from, range.to), function (row) {
	        _this5.heights[row] = void 0;
	      });
	    }
	
	    /**
	     * @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;
	      this.calculateRowsHeight({ from: this.getFirstVisibleRow(), to: this.getLastVisibleRow() }, void 0, force);
	
	      var fixedRowsBottom = this.hot.getSettings().fixedRowsBottom;
	
	      // 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) {
	      if (isDblClick) {
	        this.calculateRowsHeight(row, void 0, true);
	        size = this.getRowHeight(row);
	      }
	
	      return size;
	    }
	
	    /**
	     * 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);
	      }
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      this.ghostTable.clean();
	      _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return AutoRowSize;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('autoRowSize', AutoRowSize);
	
	exports.default = AutoRowSize;
	
	/***/ }),
	/* 252 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _moment = __webpack_require__(50);
	
	var _moment2 = _interopRequireDefault(_moment);
	
	var _element = __webpack_require__(0);
	
	var _array = __webpack_require__(2);
	
	var _mixed = __webpack_require__(22);
	
	var _object = __webpack_require__(1);
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _plugins = __webpack_require__(5);
	
	var _mergeSort = __webpack_require__(253);
	
	var _mergeSort2 = _interopRequireDefault(_mergeSort);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	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; }
	
	_pluginHooks2.default.getSingleton().register('beforeColumnSort');
	_pluginHooks2.default.getSingleton().register('afterColumnSort');
	
	// TODO: Implement mixin arrayMapper to ColumnSorting plugin.
	
	/**
	 * @plugin ColumnSorting
	 *
	 * @description
	 * This plugin sorts the view by a column (but does not sort the data source!).
	 * To enable the plugin, set the `columnSorting` property to either:
	 * * a boolean value (`true`/`false`),
	 * * an object defining the initial sorting order (see the example below).
	 *
	 * @example
	 * ```js
	 * ...
	 * // as boolean
	 * columnSorting: true
	 * ...
	 * // as a object with initial order (sort ascending column at index 2)
	 * columnSorting: {
	 *  column: 2,
	 *  sortOrder: true, // true = ascending, false = descending, undefined = original order
	 *  sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
	 * }
	 * ...
	 * ```
	 * @dependencies ObserveChanges
	 */
	
	var ColumnSorting = function (_BasePlugin) {
	  _inherits(ColumnSorting, _BasePlugin);
	
	  function ColumnSorting(hotInstance) {
	    _classCallCheck(this, ColumnSorting);
	
	    var _this2 = _possibleConstructorReturn(this, (ColumnSorting.__proto__ || Object.getPrototypeOf(ColumnSorting)).call(this, hotInstance));
	
	    _this2.sortIndicators = [];
	    _this2.lastSortedColumn = null;
	    _this2.sortEmptyCells = false;
	    return _this2;
	  }
	
	  /**
	   * Check if the plugin is enabled in the handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ColumnSorting, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return !!this.hot.getSettings().columnSorting;
	    }
	
	    /**
	     * Enable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'enablePlugin',
	    value: function enablePlugin() {
	      var _this3 = this;
	
	      if (this.enabled) {
	        return;
	      }
	
	      this.setPluginOptions();
	
	      var _this = this;
	      this.hot.sortIndex = [];
	
	      this.hot.sort = function () {
	        var args = Array.prototype.slice.call(arguments);
	
	        return _this.sortByColumn.apply(_this, _toConsumableArray(args));
	      };
	
	      if (typeof this.hot.getSettings().observeChanges === 'undefined') {
	        this.enableObserveChangesPlugin();
	      }
	
	      this.addHook('afterTrimRow', function (row) {
	        return _this3.sort();
	      });
	      this.addHook('afterUntrimRow', function (row) {
	        return _this3.sort();
	      });
	      this.addHook('modifyRow', function (row) {
	        return _this3.translateRow(row);
	      });
	      this.addHook('unmodifyRow', function (row) {
	        return _this3.untranslateRow(row);
	      });
	      this.addHook('afterUpdateSettings', function () {
	        return _this3.onAfterUpdateSettings();
	      });
	      this.addHook('afterGetColHeader', function (col, TH) {
	        return _this3.getColHeader(col, TH);
	      });
	      this.addHook('afterOnCellMouseDown', function (event, target) {
	        return _this3.onAfterOnCellMouseDown(event, target);
	      });
	      this.addHook('afterCreateRow', function () {
	        _this.afterCreateRow.apply(_this, arguments);
	      });
	      this.addHook('afterRemoveRow', function () {
	        _this.afterRemoveRow.apply(_this, arguments);
	      });
	      this.addHook('afterInit', function () {
	        return _this3.sortBySettings();
	      });
	      this.addHook('afterLoadData', function () {
	        _this3.hot.sortIndex = [];
	
	        if (_this3.hot.view) {
	          _this3.sortBySettings();
	        }
	      });
	      if (this.hot.view) {
	        this.sortBySettings();
	      }
	      _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      this.hot.sort = void 0;
	      _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * afterUpdateSettings callback.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'onAfterUpdateSettings',
	    value: function onAfterUpdateSettings() {
	      this.sortBySettings();
	    }
	  }, {
	    key: 'sortBySettings',
	    value: function sortBySettings() {
	      var sortingSettings = this.hot.getSettings().columnSorting;
	      var loadedSortingState = this.loadSortingState();
	      var sortingColumn = void 0;
	      var sortingOrder = void 0;
	
	      if (typeof loadedSortingState === 'undefined') {
	        sortingColumn = sortingSettings.column;
	        sortingOrder = sortingSettings.sortOrder;
	      } else {
	        sortingColumn = loadedSortingState.sortColumn;
	        sortingOrder = loadedSortingState.sortOrder;
	      }
	      if (typeof sortingColumn === 'number') {
	        this.lastSortedColumn = sortingColumn;
	        this.sortByColumn(sortingColumn, sortingOrder);
	      }
	    }
	
	    /**
	     * Set sorted column and order info
	     *
	     * @param {number} col Sorted visual column index.
	     * @param {boolean|undefined} order Sorting order (`true` for ascending, `false` for descending).
	     */
	
	  }, {
	    key: 'setSortingColumn',
	    value: function setSortingColumn(col, order) {
	      if (typeof col == 'undefined') {
	        this.hot.sortColumn = void 0;
	        this.hot.sortOrder = void 0;
	
	        return;
	      } else if (this.hot.sortColumn === col && typeof order == 'undefined') {
	        if (this.hot.sortOrder === false) {
	          this.hot.sortOrder = void 0;
	        } else {
	          this.hot.sortOrder = !this.hot.sortOrder;
	        }
	      } else {
	        this.hot.sortOrder = typeof order === 'undefined' ? true : order;
	      }
	
	      this.hot.sortColumn = col;
	    }
	  }, {
	    key: 'sortByColumn',
	    value: function sortByColumn(col, order) {
	      this.setSortingColumn(col, order);
	
	      if (typeof this.hot.sortColumn == 'undefined') {
	        return;
	      }
	
	      var allowSorting = this.hot.runHooks('beforeColumnSort', this.hot.sortColumn, this.hot.sortOrder);
	
	      if (allowSorting !== false) {
	        this.sort();
	      }
	      this.updateOrderClass();
	      this.updateSortIndicator();
	
	      this.hot.runHooks('afterColumnSort', this.hot.sortColumn, this.hot.sortOrder);
	
	      this.hot.render();
	      this.saveSortingState();
	    }
	
	    /**
	     * Save the sorting state
	     */
	
	  }, {
	    key: 'saveSortingState',
	    value: function saveSortingState() {
	      var sortingState = {};
	
	      if (typeof this.hot.sortColumn != 'undefined') {
	        sortingState.sortColumn = this.hot.sortColumn;
	      }
	
	      if (typeof this.hot.sortOrder != 'undefined') {
	        sortingState.sortOrder = this.hot.sortOrder;
	      }
	
	      if ((0, _object.hasOwnProperty)(sortingState, 'sortColumn') || (0, _object.hasOwnProperty)(sortingState, 'sortOrder')) {
	        this.hot.runHooks('persistentStateSave', 'columnSorting', sortingState);
	      }
	    }
	
	    /**
	     * Load the sorting state.
	     *
	     * @returns {*} Previously saved sorting state.
	     */
	
	  }, {
	    key: 'loadSortingState',
	    value: function loadSortingState() {
	      var storedState = {};
	      this.hot.runHooks('persistentStateLoad', 'columnSorting', storedState);
	
	      return storedState.value;
	    }
	
	    /**
	     * Update sorting class name state.
	     */
	
	  }, {
	    key: 'updateOrderClass',
	    value: function updateOrderClass() {
	      var orderClass = void 0;
	
	      if (this.hot.sortOrder === true) {
	        orderClass = 'ascending';
	      } else if (this.hot.sortOrder === false) {
	        orderClass = 'descending';
	      }
	      this.sortOrderClass = orderClass;
	    }
	  }, {
	    key: 'enableObserveChangesPlugin',
	    value: function enableObserveChangesPlugin() {
	      var _this = this;
	
	      this.hot._registerTimeout(setTimeout(function () {
	        _this.hot.updateSettings({
	          observeChanges: true
	        });
	      }, 0));
	    }
	
	    /**
	     * Default sorting algorithm.
	     *
	     * @param {Boolean} sortOrder Sorting order - `true` for ascending, `false` for descending.
	     * @param {Object} columnMeta Column meta object.
	     * @returns {Function} The comparing function.
	     */
	
	  }, {
	    key: 'defaultSort',
	    value: function defaultSort(sortOrder, columnMeta) {
	      return function (a, b) {
	        if (typeof a[1] == 'string') {
	          a[1] = a[1].toLowerCase();
	        }
	        if (typeof b[1] == 'string') {
	          b[1] = b[1].toLowerCase();
	        }
	
	        if (a[1] === b[1]) {
	          return 0;
	        }
	
	        if ((0, _mixed.isEmpty)(a[1])) {
	          if ((0, _mixed.isEmpty)(b[1])) {
	            return 0;
	          }
	
	          if (columnMeta.columnSorting.sortEmptyCells) {
	            return sortOrder ? -1 : 1;
	          }
	
	          return 1;
	        }
	        if ((0, _mixed.isEmpty)(b[1])) {
	          if ((0, _mixed.isEmpty)(a[1])) {
	            return 0;
	          }
	
	          if (columnMeta.columnSorting.sortEmptyCells) {
	            return sortOrder ? 1 : -1;
	          }
	
	          return -1;
	        }
	
	        if (isNaN(a[1]) && !isNaN(b[1])) {
	          return sortOrder ? 1 : -1;
	        } else if (!isNaN(a[1]) && isNaN(b[1])) {
	          return sortOrder ? -1 : 1;
	        } else if (!(isNaN(a[1]) || isNaN(b[1]))) {
	          a[1] = parseFloat(a[1]);
	          b[1] = parseFloat(b[1]);
	        }
	        if (a[1] < b[1]) {
	          return sortOrder ? -1 : 1;
	        }
	        if (a[1] > b[1]) {
	          return sortOrder ? 1 : -1;
	        }
	
	        return 0;
	      };
	    }
	
	    /**
	     * Date sorting algorithm
	     * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending).
	     * @param {Object} columnMeta Column meta object.
	     * @returns {Function} The compare function.
	     */
	
	  }, {
	    key: 'dateSort',
	    value: function dateSort(sortOrder, columnMeta) {
	      return function (a, b) {
	        if (a[1] === b[1]) {
	          return 0;
	        }
	
	        if ((0, _mixed.isEmpty)(a[1])) {
	          if ((0, _mixed.isEmpty)(b[1])) {
	            return 0;
	          }
	
	          if (columnMeta.columnSorting.sortEmptyCells) {
	            return sortOrder ? -1 : 1;
	          }
	
	          return 1;
	        }
	
	        if ((0, _mixed.isEmpty)(b[1])) {
	          if ((0, _mixed.isEmpty)(a[1])) {
	            return 0;
	          }
	
	          if (columnMeta.columnSorting.sortEmptyCells) {
	            return sortOrder ? 1 : -1;
	          }
	
	          return -1;
	        }
	
	        var aDate = (0, _moment2.default)(a[1], columnMeta.dateFormat);
	        var bDate = (0, _moment2.default)(b[1], columnMeta.dateFormat);
	
	        if (!aDate.isValid()) {
	          return 1;
	        }
	        if (!bDate.isValid()) {
	          return -1;
	        }
	
	        if (bDate.isAfter(aDate)) {
	          return sortOrder ? -1 : 1;
	        }
	        if (bDate.isBefore(aDate)) {
	          return sortOrder ? 1 : -1;
	        }
	
	        return 0;
	      };
	    }
	
	    /**
	     * Numeric sorting algorithm.
	     *
	     * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending).
	     * @param {Object} columnMeta Column meta object.
	     * @returns {Function} The compare function.
	     */
	
	  }, {
	    key: 'numericSort',
	    value: function numericSort(sortOrder, columnMeta) {
	      return function (a, b) {
	        var parsedA = parseFloat(a[1]);
	        var parsedB = parseFloat(b[1]);
	
	        // Watch out when changing this part of code!
	        // Check below returns 0 (as expected) when comparing empty string, null, undefined
	        if (parsedA === parsedB || isNaN(parsedA) && isNaN(parsedB)) {
	          return 0;
	        }
	
	        if (columnMeta.columnSorting.sortEmptyCells) {
	          if ((0, _mixed.isEmpty)(a[1])) {
	            return sortOrder ? -1 : 1;
	          }
	
	          if ((0, _mixed.isEmpty)(b[1])) {
	            return sortOrder ? 1 : -1;
	          }
	        }
	
	        if (isNaN(parsedA)) {
	          return 1;
	        }
	
	        if (isNaN(parsedB)) {
	          return -1;
	        }
	
	        if (parsedA < parsedB) {
	          return sortOrder ? -1 : 1;
	        } else if (parsedA > parsedB) {
	          return sortOrder ? 1 : -1;
	        }
	
	        return 0;
	      };
	    }
	
	    /**
	     * Perform the sorting.
	     */
	
	  }, {
	    key: 'sort',
	    value: function sort() {
	      if (typeof this.hot.sortOrder == 'undefined') {
	        this.hot.sortIndex.length = 0;
	
	        return;
	      }
	
	      var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn);
	      var emptyRows = this.hot.countEmptyRows();
	      var sortFunction = void 0;
	      var nrOfRows = void 0;
	
	      this.hot.sortingEnabled = false; // this is required by translateRow plugin hook
	      this.hot.sortIndex.length = 0;
	
	      if (typeof colMeta.columnSorting.sortEmptyCells === 'undefined') {
	        colMeta.columnSorting = { sortEmptyCells: this.sortEmptyCells };
	      }
	
	      if (this.hot.getSettings().maxRows === Number.POSITIVE_INFINITY) {
	        nrOfRows = this.hot.countRows() - this.hot.getSettings().minSpareRows;
	      } else {
	        nrOfRows = this.hot.countRows() - emptyRows;
	      }
	
	      for (var i = 0, ilen = nrOfRows; i < ilen; i++) {
	        this.hot.sortIndex.push([i, this.hot.getDataAtCell(i, this.hot.sortColumn)]);
	      }
	
	      if (colMeta.sortFunction) {
	        sortFunction = colMeta.sortFunction;
	      } else {
	        switch (colMeta.type) {
	          case 'date':
	            sortFunction = this.dateSort;
	            break;
	          case 'numeric':
	            sortFunction = this.numericSort;
	            break;
	          default:
	            sortFunction = this.defaultSort;
	        }
	      }
	
	      (0, _mergeSort2.default)(this.hot.sortIndex, sortFunction(this.hot.sortOrder, colMeta));
	
	      // Append spareRows
	      for (var _i = this.hot.sortIndex.length; _i < this.hot.countRows(); _i++) {
	        this.hot.sortIndex.push([_i, this.hot.getDataAtCell(_i, this.hot.sortColumn)]);
	      }
	
	      this.hot.sortingEnabled = true; // this is required by translateRow plugin hook
	    }
	
	    /**
	     * Update indicator states.
	     */
	
	  }, {
	    key: 'updateSortIndicator',
	    value: function updateSortIndicator() {
	      if (typeof this.hot.sortOrder == 'undefined') {
	        return;
	      }
	      var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn);
	
	      this.sortIndicators[this.hot.sortColumn] = colMeta.sortIndicator;
	    }
	
	    /**
	     * `modifyRow` hook callback. Translates physical row index to the sorted row index.
	     *
	     * @param {Number} row Row index.
	     * @returns {Number} Sorted row index.
	     */
	
	  }, {
	    key: 'translateRow',
	    value: function translateRow(row) {
	      if (this.hot.sortingEnabled && typeof this.hot.sortOrder !== 'undefined' && this.hot.sortIndex && this.hot.sortIndex.length && this.hot.sortIndex[row]) {
	        return this.hot.sortIndex[row][0];
	      }
	
	      return row;
	    }
	
	    /**
	     * Translates sorted row index to physical row index.
	     *
	     * @param {Number} row Sorted (visual) row index.
	     * @returns {number} Physical row index.
	     */
	
	  }, {
	    key: 'untranslateRow',
	    value: function untranslateRow(row) {
	      if (this.hot.sortingEnabled && this.hot.sortIndex && this.hot.sortIndex.length) {
	        for (var i = 0; i < this.hot.sortIndex.length; i++) {
	          if (this.hot.sortIndex[i][0] == row) {
	            return i;
	          }
	        }
	      }
	    }
	
	    /**
	     * `afterGetColHeader` callback. Adds column sorting css classes to clickable headers.
	     *
	     * @private
	     * @param {Number} col Visual column index.
	     * @param {Element} TH TH HTML element.
	     */
	
	  }, {
	    key: 'getColHeader',
	    value: function getColHeader(col, TH) {
	      if (col < 0 || !TH.parentNode) {
	        return false;
	      }
	
	      var headerLink = TH.querySelector('.colHeader');
	      var colspan = TH.getAttribute('colspan');
	      var TRs = TH.parentNode.parentNode.childNodes;
	      var headerLevel = Array.prototype.indexOf.call(TRs, TH.parentNode);
	      headerLevel -= TRs.length;
	
	      if (!headerLink) {
	        return;
	      }
	
	      if (this.hot.getSettings().columnSorting && col >= 0 && headerLevel === -1) {
	        (0, _element.addClass)(headerLink, 'columnSorting');
	      }
	      (0, _element.removeClass)(headerLink, 'descending');
	      (0, _element.removeClass)(headerLink, 'ascending');
	
	      if (this.sortIndicators[col]) {
	        if (col === this.hot.sortColumn) {
	          if (this.sortOrderClass === 'ascending') {
	            (0, _element.addClass)(headerLink, 'ascending');
	          } else if (this.sortOrderClass === 'descending') {
	            (0, _element.addClass)(headerLink, 'descending');
	          }
	        }
	      }
	    }
	
	    /**
	     * Check if any column is in a sorted state.
	     *
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'isSorted',
	    value: function isSorted() {
	      return typeof this.hot.sortColumn != 'undefined';
	    }
	
	    /**
	     * `afterCreateRow` callback. Updates the sorting state after a row have been created.
	     *
	     * @private
	     * @param {Number} index Visual row index.
	     * @param {Number} amount
	     */
	
	  }, {
	    key: 'afterCreateRow',
	    value: function afterCreateRow(index, amount) {
	      if (!this.isSorted()) {
	        return;
	      }
	
	      for (var i = 0; i < this.hot.sortIndex.length; i++) {
	        if (this.hot.sortIndex[i][0] >= index) {
	          this.hot.sortIndex[i][0] += amount;
	        }
	      }
	
	      for (var _i2 = 0; _i2 < amount; _i2++) {
	        this.hot.sortIndex.splice(index + _i2, 0, [index + _i2, this.hot.getSourceData()[index + _i2][this.hot.sortColumn + this.hot.colOffset()]]);
	      }
	
	      this.saveSortingState();
	    }
	
	    /**
	     * `afterRemoveRow` hook callback.
	     *
	     * @private
	     * @param {Number} index Visual row index.
	     * @param {Number} amount
	     */
	
	  }, {
	    key: 'afterRemoveRow',
	    value: function afterRemoveRow(index, amount) {
	      if (!this.isSorted()) {
	        return;
	      }
	      var removedRows = this.hot.sortIndex.splice(index, amount);
	
	      removedRows = (0, _array.arrayMap)(removedRows, function (row) {
	        return row[0];
	      });
	
	      function countRowShift(logicalRow) {
	        // Todo: compare perf between reduce vs sort->each->brake
	        return (0, _array.arrayReduce)(removedRows, function (count, removedLogicalRow) {
	          if (logicalRow > removedLogicalRow) {
	            count++;
	          }
	
	          return count;
	        }, 0);
	      }
	
	      this.hot.sortIndex = (0, _array.arrayMap)(this.hot.sortIndex, function (logicalRow, physicalRow) {
	        var rowShift = countRowShift(logicalRow[0]);
	
	        if (rowShift) {
	          logicalRow[0] -= rowShift;
	        }
	
	        return logicalRow;
	      });
	
	      this.saveSortingState();
	    }
	
	    /**
	     * Set options by passed settings
	     *
	     * @private
	     */
	
	  }, {
	    key: 'setPluginOptions',
	    value: function setPluginOptions() {
	      var columnSorting = this.hot.getSettings().columnSorting;
	
	      if ((typeof columnSorting === 'undefined' ? 'undefined' : _typeof(columnSorting)) === 'object') {
	        this.sortEmptyCells = columnSorting.sortEmptyCells || false;
	      } else {
	        this.sortEmptyCells = false;
	      }
	    }
	
	    /**
	     * `onAfterOnCellMouseDown` hook callback.
	     *
	     * @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 (coords.row > -1) {
	        return;
	      }
	
	      if ((0, _element.hasClass)(event.realTarget, 'columnSorting')) {
	        // reset order state on every new column header click
	        if (coords.col !== this.lastSortedColumn) {
	          this.hot.sortOrder = true;
	        }
	
	        this.lastSortedColumn = coords.col;
	
	        this.sortByColumn(coords.col);
	      }
	    }
	  }]);
	
	  return ColumnSorting;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('columnSorting', ColumnSorting);
	
	exports.default = ColumnSorting;
	
	/***/ }),
	/* 253 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = mergeSort;
	exports.merge = merge;
	
	var _linkedList = __webpack_require__(254);
	
	var _linkedList2 = _interopRequireDefault(_linkedList);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * 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 _linkedList2.default();
	  var rightElements = new _linkedList2.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;
	};
	
	/***/ }),
	/* 254 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * 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) {
	  _classCallCheck(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
	 */
	
	
	var LinkedList = function () {
	  function LinkedList() {
	    _classCallCheck(this, LinkedList);
	
	    this.first = null;
	    this.last = null;
	  }
	
	  /**
	   * Add data to the end of linked list.
	   *
	   * @param {Object} data Data which should be added.
	   */
	
	
	  _createClass(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 = void 0;
	      var prev = void 0;
	
	      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;
	        }
	      }
	    }
	  }, {
	    key: "pop",
	
	
	    /**
	     * Return last node from the linked list.
	     *
	     * @returns {NodeStructure} Last node.
	     */
	    value: function pop() {
	      if (this.last === null) {
	        return null;
	      }
	
	      var temp = this.last;
	      this.last = this.last.prev;
	
	      return temp;
	    }
	  }, {
	    key: "shift",
	
	
	    /**
	     * Return first node from the linked list.
	     *
	     * @returns {NodeStructure} First node.
	     */
	    value: function shift() {
	      if (this.first === null) {
	        return null;
	      }
	
	      var temp = this.first;
	      this.first = this.first.next;
	
	      return temp;
	    }
	  }, {
	    key: "recursiveReverse",
	
	
	    /**
	     * Reverses the linked list recursively
	     */
	    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;
	    }
	  }, {
	    key: "reverse",
	
	
	    /**
	     * Reverses the linked list iteratively
	     */
	    value: function reverse() {
	      if (!this.first || !this.first.next) {
	        return;
	      }
	
	      var current = this.first.next;
	      var prev = this.first;
	      var temp = void 0;
	
	      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;
	}();
	
	;
	
	exports.NodeStructure = NodeStructure;
	exports.default = LinkedList;
	
	/***/ }),
	/* 255 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _element = __webpack_require__(0);
	
	var _object = __webpack_require__(1);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _src = __webpack_require__(12);
	
	var _plugins = __webpack_require__(5);
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _commentEditor = __webpack_require__(256);
	
	var _commentEditor2 = _interopRequireDefault(_commentEditor);
	
	var _utils = __webpack_require__(19);
	
	var _displaySwitch = __webpack_require__(257);
	
	var _displaySwitch2 = _interopRequireDefault(_displaySwitch);
	
	__webpack_require__(258);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	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; }
	
	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; }
	
	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 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
	 * ...
	 * var 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:
	 * var 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({row: 1, col: 6});
	 * commentsPlugin.setComment('Comment contents');
	 * commentsPlugin.show();
	 * commentsPlugin.removeComment();
	 * ...
	 * ```
	 */
	
	var Comments = function (_BasePlugin) {
	  _inherits(Comments, _BasePlugin);
	
	  function Comments(hotInstance) {
	    _classCallCheck(this, Comments);
	
	    /**
	     * Instance of {@link CommentEditor}.
	     *
	     * @type {CommentEditor}
	     */
	    var _this = _possibleConstructorReturn(this, (Comments.__proto__ || Object.getPrototypeOf(Comments)).call(this, hotInstance));
	
	    _this.editor = null;
	    /**
	     * Instance of {@link DisplaySwitch}.
	     *
	     * @type {DisplaySwitch}
	     */
	    _this.displaySwitch = null;
	    /**
	     * Instance of {@link EventManager}.
	     *
	     * @private
	     * @type {EventManager}
	     */
	    _this.eventManager = null;
	    /**
	     * Current cell range.
	     *
	     * @type {Object}
	     */
	    _this.range = {};
	    /**
	     * @private
	     * @type {Boolean}
	     */
	    _this.mouseDown = false;
	    /**
	     * @private
	     * @type {Boolean}
	     */
	    _this.contextMenuEvent = false;
	    /**
	     * @private
	     * @type {*}
	     */
	    _this.timer = null;
	
	    privatePool.set(_this, {
	      tempEditorDimensions: {},
	      cellBelowCursor: null
	    });
	    return _this;
	  }
	
	  /**
	   * Check if the plugin is enabled in the Handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(Comments, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return !!this.hot.getSettings().comments;
	    }
	
	    /**
	     * Enable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'enablePlugin',
	    value: function enablePlugin() {
	      var _this2 = this;
	
	      if (this.enabled) {
	        return;
	      }
	
	      if (!this.editor) {
	        this.editor = new _commentEditor2.default();
	      }
	
	      if (!this.eventManager) {
	        this.eventManager = new _eventManager2.default(this);
	      }
	
	      if (!this.displaySwitch) {
	        this.displaySwitch = new _displaySwitch2.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 (args) {
	        return _this2.onAfterBeginEditing(args);
	      });
	
	      this.displaySwitch.addLocalHook('hide', function () {
	        return _this2.hide();
	      });
	      this.displaySwitch.addLocalHook('show', function (row, col) {
	        return _this2.showAtCell(row, col);
	      });
	
	      this.registerListeners();
	
	      _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Update plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      this.disablePlugin();
	      this.enablePlugin();
	      _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'updatePlugin', this).call(this);
	
	      this.displaySwitch.updateDelay(this.getDisplayDelaySetting());
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Register all necessary DOM listeners.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'registerListeners',
	    value: function registerListeners() {
	      var _this3 = this;
	
	      this.eventManager.addEventListener(document, 'mouseover', function (event) {
	        return _this3.onMouseOver(event);
	      });
	      this.eventManager.addEventListener(document, 'mousedown', function (event) {
	        return _this3.onMouseDown(event);
	      });
	      this.eventManager.addEventListener(document, 'mouseup', function (event) {
	        return _this3.onMouseUp(event);
	      });
	      this.eventManager.addEventListener(this.editor.getInputElement(), 'blur', function (event) {
	        return _this3.onEditorBlur(event);
	      });
	      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);
	      });
	    }
	
	    /**
	     * Set 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` and `to` properties, each with `row` and `col` properties.
	     */
	
	  }, {
	    key: 'setRange',
	    value: function setRange(range) {
	      this.range = range;
	    }
	
	    /**
	     * Clear the currently selected cell.
	     */
	
	  }, {
	    key: 'clearRange',
	    value: function clearRange() {
	      this.range = {};
	    }
	
	    /**
	     * Check if the event target is a cell containing a comment.
	     *
	     * @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]));
	    }
	
	    /**
	     * Check if the event target is a comment textarea.
	     *
	     * @param {Event} event DOM event.
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'targetIsCommentTextArea',
	    value: function targetIsCommentTextArea(event) {
	      return this.editor.getInputElement() === event.target;
	    }
	
	    /**
	     * Set 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) {
	        comment = value;
	      } else if (editorValue != null) {
	        comment = editorValue;
	      }
	
	      var row = this.range.from.row;
	      var col = this.range.from.col;
	
	      this.updateCommentMeta(row, col, _defineProperty({}, META_COMMENT_VALUE, comment));
	      this.hot.render();
	    }
	
	    /**
	     * Set a comment for a cell.
	     *
	     * @param {Number} row Visual row index.
	     * @param {Number} col Visual column index.
	     * @param {String} value Comment contents.
	     */
	
	  }, {
	    key: 'setCommentAtCell',
	    value: function setCommentAtCell(row, col, value) {
	      this.setRange({
	        from: new _src.CellCoords(row, col)
	      });
	      this.setComment(value);
	    }
	
	    /**
	     * Remove 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();
	    }
	
	    /**
	     * Remove comment from a cell.
	     *
	     * @param {Number} row Visual row index.
	     * @param {Number} col 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, col) {
	      var forceRender = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
	
	      this.setRange({
	        from: new _src.CellCoords(row, col)
	      });
	      this.removeComment(forceRender);
	    }
	
	    /**
	     * Get comment from a cell at the predefined range.
	     */
	
	  }, {
	    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);
	    }
	
	    /**
	     * Get comment from a cell at the provided coordinates.
	     *
	     * @param {Number} row Visual row index.
	     * @param {Number} column Visual column index.
	     */
	
	  }, {
	    key: 'getCommentAtCell',
	    value: function getCommentAtCell(row, column) {
	      return this.getCommentMeta(row, column, META_COMMENT_VALUE);
	    }
	
	    /**
	     * Show 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] : null || '');
	
	      if (this.editor.hidden) {
	        this.editor.show();
	      }
	
	      return true;
	    }
	
	    /**
	     * Show comment editor according to cell coordinates.
	     *
	     * @param {Number} row Visual row index.
	     * @param {Number} col Visual column index.
	     * @returns {Boolean} Returns `true` if comment editor was shown.
	     */
	
	  }, {
	    key: 'showAtCell',
	    value: function showAtCell(row, col) {
	      this.setRange({
	        from: new _src.CellCoords(row, col)
	      });
	
	      return this.show();
	    }
	
	    /**
	     * Hide the comment editor.
	     */
	
	  }, {
	    key: 'hide',
	    value: function hide() {
	      if (!this.editor.hidden) {
	        this.editor.hide();
	      }
	    }
	
	    /**
	     * Refresh 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 scrollableElement = (0, _element.getScrollableElement)(this.hot.view.wt.wtTable.TABLE);
	      var TD = this.hot.view.wt.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 = this.hot.view.wt.wtTable.getStretchedColumnWidth(column);
	      var cellTopOffset = cellOffset.top < 0 ? 0 : cellOffset.top;
	      var cellLeftOffset = cellOffset.left;
	
	      if (this.hot.view.wt.wtViewport.hasVerticalScroll() && scrollableElement !== window) {
	        cellTopOffset -= this.hot.view.wt.wtOverlays.topOverlay.getScrollPosition();
	      }
	
	      if (this.hot.view.wt.wtViewport.hasHorizontalScroll() && scrollableElement !== window) {
	        cellLeftOffset -= this.hot.view.wt.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);
	    }
	
	    /**
	     * Check if there is a comment for selected range.
	     *
	     * @private
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'checkSelectionCommentsConsistency',
	    value: function checkSelectionCommentsConsistency() {
	      var selected = this.hot.getSelectedRange();
	
	      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;
	    }
	
	    /**
	     * Set 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 = void 0;
	
	      if (oldComment) {
	        newComment = (0, _object.deepClone)(oldComment);
	        (0, _object.deepExtend)(newComment, metaObject);
	      } else {
	        newComment = metaObject;
	      }
	
	      this.hot.setCellMeta(row, column, META_COMMENT, newComment);
	    }
	
	    /**
	     * Get 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);
	
	      priv.cellBelowCursor = document.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, document) && !this.targetIsCommentTextArea(event)) {
	        this.displaySwitch.hide();
	      }
	    }
	
	    /**
	     * `mouseup` event callback.
	     *
	     * @private
	     * @param {MouseEvent} event The `mouseup` event.
	     */
	
	  }, {
	    key: 'onMouseUp',
	    value: function onMouseUp(event) {
	      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
	     * @param {Event} event The `blur` event.
	     */
	
	  }, {
	    key: 'onEditorBlur',
	    value: function onEditorBlur(event) {
	      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, _defineProperty({}, 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.getSelectedRange();
	
	      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
	     * @param {Object} selection The current selection.
	     */
	
	  }, {
	    key: 'onContextMenuRemoveComment',
	    value: function onContextMenuRemoveComment(selection) {
	      this.contextMenuEvent = true;
	
	      for (var i = selection.start.row; i <= selection.end.row; i++) {
	        for (var j = selection.start.col; j <= selection.end.col; j++) {
	          this.removeCommentAtCell(i, j, false);
	        }
	      }
	
	      this.hot.render();
	    }
	
	    /**
	     * Context Menu's "make comment read-only" callback.
	     *
	     * @private
	     * @param {Object} selection The current selection.
	     */
	
	  }, {
	    key: 'onContextMenuMakeReadOnly',
	    value: function onContextMenuMakeReadOnly(selection) {
	      this.contextMenuEvent = true;
	
	      for (var i = selection.start.row; i <= selection.end.row; i++) {
	        for (var j = selection.start.col; j <= selection.end.col; j++) {
	          var currentState = !!this.getCommentMeta(i, j, META_READONLY);
	
	          this.updateCommentMeta(i, j, _defineProperty({}, 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() {
	          return _this5.checkSelectionCommentsConsistency() ? 'Edit comment' : 'Add comment';
	        },
	        callback: function callback() {
	          return _this5.onContextMenuAddComment();
	        },
	        disabled: function disabled() {
	          return !(this.getSelected() && !this.selection.selectedHeader.corner);
	        }
	      }, {
	        key: 'commentsRemove',
	        name: function name() {
	          return 'Delete comment';
	        },
	
	        callback: function callback(key, selection) {
	          return _this5.onContextMenuRemoveComment(selection);
	        },
	        disabled: function disabled() {
	          return _this5.hot.selection.selectedHeader.corner;
	        }
	      }, {
	        key: 'commentsReadOnly',
	        name: function name() {
	          var _this6 = this;
	
	          var label = 'Read only comment';
	          var hasProperty = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), 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(key, selection) {
	          return _this5.onContextMenuMakeReadOnly(selection);
	        },
	        disabled: function disabled() {
	          return _this5.hot.selection.selectedHeader.corner || !_this5.checkSelectionCommentsConsistency();
	        }
	      });
	    }
	
	    /**
	     * Get `displayDelay` setting of comment plugin.
	     *
	     * @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
	     * @param {Number} row Visual row index of the currently edited cell.
	     * @param {Number} column Visual column index of the currently edited cell.
	     */
	
	  }, {
	    key: 'onAfterBeginEditing',
	    value: function onAfterBeginEditing(row, column) {
	      this.hide();
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      if (this.editor) {
	        this.editor.destroy();
	      }
	
	      if (this.displaySwitch) {
	        this.displaySwitch.destroy();
	      }
	
	      _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return Comments;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('comments', Comments);
	
	exports.default = Comments;
	
	/***/ }),
	/* 256 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * Comment editor for the Comments plugin.
	 *
	 * @class CommentEditor
	 * @plugin Comments
	 */
	var CommentEditor = function () {
	  _createClass(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() {
	    _classCallCheck(this, CommentEditor);
	
	    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).
	   */
	
	
	  _createClass(CommentEditor, [{
	    key: 'setPosition',
	    value: function setPosition(x, y) {
	      this.editorStyle.left = x + 'px';
	      this.editorStyle.top = 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 = width + 'px';
	        input.style.height = 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] : '';
	
	      value = value || '';
	      this.getInputElement().value = value;
	    }
	
	    /**
	     * 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 document.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 container = document.querySelector('.' + CommentEditor.CLASS_EDITOR_CONTAINER);
	      var editor = void 0;
	      var textArea = void 0;
	
	      if (!container) {
	        container = document.createElement('div');
	        (0, _element.addClass)(container, CommentEditor.CLASS_EDITOR_CONTAINER);
	        document.body.appendChild(container);
	      }
	      editor = document.createElement('div');
	      (0, _element.addClass)(editor, CommentEditor.CLASS_EDITOR);
	
	      textArea = document.createElement('textarea');
	      (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('.' + 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;
	}();
	
	exports.default = CommentEditor;
	
	/***/ }),
	/* 257 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _function = __webpack_require__(35);
	
	var _object = __webpack_require__(1);
	
	var _localHooks = __webpack_require__(87);
	
	var _localHooks2 = _interopRequireDefault(_localHooks);
	
	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"); } }
	
	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 = function () {
	  function DisplaySwitch(displayDelay) {
	    _classCallCheck(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.
	   */
	
	
	  _createClass(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);
	    }
	  }, {
	    key: 'cancelHiding',
	
	
	    /**
	     * Cancel hiding comment.
	     */
	    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, _localHooks2.default);
	
	exports.default = DisplaySwitch;
	
	/***/ }),
	/* 258 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 259 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _array = __webpack_require__(2);
	
	var _commandExecutor = __webpack_require__(260);
	
	var _commandExecutor2 = _interopRequireDefault(_commandExecutor);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _itemsFactory = __webpack_require__(261);
	
	var _itemsFactory2 = _interopRequireDefault(_itemsFactory);
	
	var _menu = __webpack_require__(273);
	
	var _menu2 = _interopRequireDefault(_menu);
	
	var _plugins = __webpack_require__(5);
	
	var _event = __webpack_require__(10);
	
	var _element = __webpack_require__(0);
	
	var _predefinedItems = __webpack_require__(88);
	
	__webpack_require__(275);
	
	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; }
	
	_pluginHooks2.default.getSingleton().register('afterContextMenuDefaultOptions');
	_pluginHooks2.default.getSingleton().register('afterContextMenuShow');
	_pluginHooks2.default.getSingleton().register('afterContextMenuHide');
	_pluginHooks2.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](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 context menu demo](http://docs.handsontable.com/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 = function (_BasePlugin) {
	  _inherits(ContextMenu, _BasePlugin);
	
	  _createClass(ContextMenu, null, [{
	    key: 'DEFAULT_ITEMS',
	
	    /**
	     * Default menu items order when `contextMenu` is enabled by `true`.
	     *
	     * @returns {Array}
	     */
	    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) {
	    _classCallCheck(this, ContextMenu);
	
	    /**
	     * Instance of {@link EventManager}.
	     *
	     * @type {EventManager}
	     */
	    var _this = _possibleConstructorReturn(this, (ContextMenu.__proto__ || Object.getPrototypeOf(ContextMenu)).call(this, hotInstance));
	
	    _this.eventManager = new _eventManager2.default(_this);
	    /**
	     * Instance of {@link CommandExecutor}.
	     *
	     * @type {CommandExecutor}
	     */
	    _this.commandExecutor = new _commandExecutor2.default(_this.hot);
	    /**
	     * Instance of {@link ItemsFactory}.
	     *
	     * @type {ItemsFactory}
	     */
	    _this.itemsFactory = null;
	    /**
	     * Instance of {@link Menu}.
	     *
	     * @type {Menu}
	     */
	    _this.menu = null;
	    return _this;
	  }
	
	  /**
	   * Check if the plugin is enabled in the Handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ContextMenu, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return this.hot.getSettings().contextMenu;
	    }
	
	    /**
	     * Enable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'enablePlugin',
	    value: function enablePlugin() {
	      var _this2 = this;
	
	      if (this.enabled) {
	        return;
	      }
	      this.itemsFactory = new _itemsFactory2.default(this.hot, ContextMenu.DEFAULT_ITEMS);
	
	      var settings = this.hot.getSettings().contextMenu;
	      var predefinedItems = {
	        items: this.itemsFactory.getItems(settings)
	      };
	      this.registerEvents();
	
	      if (typeof settings.callback === 'function') {
	        this.commandExecutor.setCommonCallback(settings.callback);
	      }
	      _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'enablePlugin', this).call(this);
	
	      this.callOnPluginsReady(function () {
	        _this2.hot.runHooks('afterContextMenuDefaultOptions', predefinedItems);
	
	        _this2.itemsFactory.setPredefinedItems(predefinedItems.items);
	        var menuItems = _this2.itemsFactory.getItems(settings);
	
	        _this2.menu = new _menu2.default(_this2.hot, {
	          className: 'htContextMenu',
	          keepInViewport: true
	        });
	        _this2.hot.runHooks('beforeContextMenuSetItems', menuItems);
	
	        _this2.menu.setMenuItems(menuItems);
	
	        _this2.menu.addLocalHook('afterOpen', function () {
	          return _this2.onMenuAfterOpen();
	        });
	        _this2.menu.addLocalHook('afterClose', function () {
	          return _this2.onMenuAfterClose();
	        });
	        _this2.menu.addLocalHook('executeCommand', function () {
	          for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
	            params[_key] = arguments[_key];
	          }
	
	          return _this2.executeCommand.apply(_this2, 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 to use the latest options you have specified.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      this.disablePlugin();
	      this.enablePlugin();
	
	      _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      this.close();
	
	      if (this.menu) {
	        this.menu.destroy();
	        this.menu = null;
	      }
	      _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Register dom listeners.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'registerEvents',
	    value: function registerEvents() {
	      var _this3 = this;
	
	      this.eventManager.addEventListener(this.hot.rootElement, 'contextmenu', function (event) {
	        return _this3.onContextMenu(event);
	      });
	    }
	
	    /**
	     * Open menu and re-position it based on dom event object.
	     *
	     * @param {Event} event The event object.
	     */
	
	  }, {
	    key: 'open',
	    value: function open(event) {
	      if (!this.menu) {
	        return;
	      }
	      this.menu.open();
	      this.menu.setPosition({
	        top: parseInt((0, _event.pageY)(event), 10) - (0, _element.getWindowScrollTop)(),
	        left: parseInt((0, _event.pageX)(event), 10) - (0, _element.getWindowScrollLeft)()
	      });
	
	      // 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;
	    }
	
	    /**
	     * Close menu.
	     */
	
	  }, {
	    key: 'close',
	    value: function close() {
	      if (!this.menu) {
	        return;
	      }
	      this.menu.close();
	    }
	
	    /**
	     * Execute context menu command.
	     *
	     * You can execute all predefined commands:
	     *  * `'row_above'` - Insert row above
	     *  * `'row_below'` - Insert row below
	     *  * `'col_left'` - Insert column on the left
	     *  * `'col_right'` - Insert column on the 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
	     * @param {*} params
	     */
	
	  }, {
	    key: 'executeCommand',
	    value: function executeCommand() {
	      for (var _len2 = arguments.length, params = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
	        params[_key2] = arguments[_key2];
	      }
	
	      this.commandExecutor.execute.apply(this.commandExecutor, params);
	    }
	
	    /**
	     * On context menu listener.
	     *
	     * @private
	     * @param {Event} event
	     */
	
	  }, {
	    key: 'onContextMenu',
	    value: function onContextMenu(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 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);
	    }
	
	    /**
	     * Destroy instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      this.close();
	
	      if (this.menu) {
	        this.menu.destroy();
	      }
	      _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return ContextMenu;
	}(_base2.default);
	
	ContextMenu.SEPARATOR = {
	  name: _predefinedItems.SEPARATOR
	};
	
	(0, _plugins.registerPlugin)('contextMenu', ContextMenu);
	
	exports.default = ContextMenu;
	
	/***/ }),
	/* 260 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _array = __webpack_require__(2);
	
	var _object = __webpack_require__(1);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * Command executor for ContextMenu.
	 *
	 * @class CommandExecutor
	 * @plugin ContextMenu
	 */
	var CommandExecutor = function () {
	  function CommandExecutor(hotInstance) {
	    _classCallCheck(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).
	   */
	
	
	  _createClass(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 = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	        params[_key - 1] = arguments[_key];
	      }
	
	      var commandSplit = commandName.split(':');
	      commandName = commandSplit[0];
	
	      var subCommandName = commandSplit.length === 2 ? commandSplit[1] : null;
	      var command = this.commands[commandName];
	
	      if (!command) {
	        throw new Error('Menu command \'' + commandName + '\' 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 = void 0;
	
	  (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;
	}
	
	exports.default = CommandExecutor;
	
	/***/ }),
	/* 261 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _object = __webpack_require__(1);
	
	var _array = __webpack_require__(2);
	
	var _predefinedItems = __webpack_require__(88);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * Predefined items class factory for menu items.
	 *
	 * @class ItemsFactory
	 * @plugin ContextMenu
	 */
	var ItemsFactory = function () {
	  function ItemsFactory(hotInstance) {
	    var orderPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
	
	    _classCallCheck(this, ItemsFactory);
	
	    this.hot = hotInstance;
	    this.predefinedItems = (0, _predefinedItems.predefinedItems)();
	    this.defaultOrderPattern = orderPattern;
	  }
	
	  /**
	   * Set predefined items.
	   *
	   * @param {Array} predefinedItems Array of predefined items.
	   */
	
	
	  _createClass(ItemsFactory, [{
	    key: 'setPredefinedItems',
	    value: function setPredefinedItems(predefinedItems) {
	      var _this = this;
	
	      var items = {};
	
	      this.defaultOrderPattern.length = 0;
	
	      (0, _object.objectEach)(predefinedItems, 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 pattern = 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 = [];
	
	  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: '' + key };
	      }
	      if ((0, _object.isObject)(name)) {
	        (0, _object.extend)(item, name);
	      }
	      if (item.key === void 0) {
	        item.key = key;
	      }
	      result.push(item);
	    });
	  }
	
	  return result;
	}
	
	exports.default = ItemsFactory;
	
	/***/ }),
	/* 262 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = alignmentItem;
	
	var _utils = __webpack_require__(19);
	
	var _separator = __webpack_require__(86);
	
	var KEY = exports.KEY = 'alignment';
	
	function alignmentItem() {
	  return {
	    key: KEY,
	    name: 'Alignment',
	    disabled: function disabled() {
	      return !(this.getSelectedRange() && !this.selection.selectedHeader.corner);
	    },
	
	    submenu: {
	      items: [{
	        key: KEY + ':left',
	        name: function name() {
	          var _this = this;
	
	          var label = '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 range = this.getSelectedRange();
	          var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
	            return _this2.getCellMeta(row, col).className;
	          });
	          var type = 'horizontal';
	          var alignment = 'htLeft';
	
	          this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
	          (0, _utils.align)(range, 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: KEY + ':center',
	        name: function name() {
	          var _this3 = this;
	
	          var label = '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 range = this.getSelectedRange();
	          var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
	            return _this4.getCellMeta(row, col).className;
	          });
	          var type = 'horizontal';
	          var alignment = 'htCenter';
	
	          this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
	          (0, _utils.align)(range, 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: KEY + ':right',
	        name: function name() {
	          var _this5 = this;
	
	          var label = '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 range = this.getSelectedRange();
	          var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
	            return _this6.getCellMeta(row, col).className;
	          });
	          var type = 'horizontal';
	          var alignment = 'htRight';
	
	          this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
	          (0, _utils.align)(range, 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: KEY + ':justify',
	        name: function name() {
	          var _this7 = this;
	
	          var label = '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 range = this.getSelectedRange();
	          var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
	            return _this8.getCellMeta(row, col).className;
	          });
	          var type = 'horizontal';
	          var alignment = 'htJustify';
	
	          this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
	          (0, _utils.align)(range, 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: KEY + ':top',
	        name: function name() {
	          var _this9 = this;
	
	          var label = '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 range = this.getSelectedRange();
	          var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
	            return _this10.getCellMeta(row, col).className;
	          });
	          var type = 'vertical';
	          var alignment = 'htTop';
	
	          this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
	          (0, _utils.align)(range, 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: KEY + ':middle',
	        name: function name() {
	          var _this11 = this;
	
	          var label = '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 range = this.getSelectedRange();
	          var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
	            return _this12.getCellMeta(row, col).className;
	          });
	          var type = 'vertical';
	          var alignment = 'htMiddle';
	
	          this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
	          (0, _utils.align)(range, 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: KEY + ':bottom',
	        name: function name() {
	          var _this13 = this;
	
	          var label = '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 range = this.getSelectedRange();
	          var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
	            return _this14.getCellMeta(row, col).className;
	          });
	          var type = 'vertical';
	          var alignment = 'htBottom';
	
	          this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
	          (0, _utils.align)(range, 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
	      }]
	    }
	  };
	}
	
	/***/ }),
	/* 263 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = clearColumnItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'clear_column';
	
	function clearColumnItem() {
	  return {
	    key: KEY,
	    name: 'Clear column',
	
	    callback: function callback(key, selection) {
	      var column = selection.start.col;
	
	      if (this.countRows()) {
	        this.populateFromArray(0, column, [[null]], Math.max(selection.start.row, selection.end.row), column, 'ContextMenu.clearColumn');
	      }
	    },
	    disabled: function disabled() {
	      var selected = (0, _utils.getValidSelection)(this);
	
	      if (!selected) {
	        return true;
	      }
	      var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1];
	      var rowSelected = entireRowSelection.join(',') == selected.join(',');
	
	      return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || rowSelected;
	    }
	  };
	}
	
	/***/ }),
	/* 264 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = columnLeftItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'col_left';
	
	function columnLeftItem() {
	  return {
	    key: KEY,
	    name: 'Insert column on the left',
	    callback: function callback(key, selection) {
	      this.alter('insert_col', selection.start.col, 1, 'ContextMenu.columnLeft');
	    },
	    disabled: function disabled() {
	      var selected = (0, _utils.getValidSelection)(this);
	
	      if (!selected) {
	        return true;
	      }
	      if (!this.isColumnModificationAllowed()) {
	        return true;
	      }
	      var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1];
	      var rowSelected = entireRowSelection.join(',') == selected.join(',');
	      var onlyOneColumn = this.countCols() === 1;
	
	      return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected;
	    },
	    hidden: function hidden() {
	      return !this.getSettings().allowInsertColumn;
	    }
	  };
	}
	
	/***/ }),
	/* 265 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = columnRightItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'col_right';
	
	function columnRightItem() {
	  return {
	    key: KEY,
	    name: 'Insert column on the right',
	
	    callback: function callback(key, selection) {
	      this.alter('insert_col', selection.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 entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1];
	      var rowSelected = entireRowSelection.join(',') == selected.join(',');
	      var onlyOneColumn = this.countCols() === 1;
	
	      return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected;
	    },
	    hidden: function hidden() {
	      return !this.getSettings().allowInsertColumn;
	    }
	  };
	}
	
	/***/ }),
	/* 266 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = readOnlyItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'make_read_only';
	
	function readOnlyItem() {
	  return {
	    key: KEY,
	    name: function name() {
	      var _this = this;
	
	      var label = '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 range = this.getSelectedRange();
	      var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(range, function (row, col) {
	        return _this2.getCellMeta(row, col).readOnly;
	      });
	
	      range.forAll(function (row, col) {
	        _this2.setCellMeta(row, col, 'readOnly', !atLeastOneReadOnly);
	      });
	      this.render();
	    },
	    disabled: function disabled() {
	      return !(this.getSelectedRange() && !this.selection.selectedHeader.corner);
	    }
	  };
	}
	
	/***/ }),
	/* 267 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = redoItem;
	var KEY = exports.KEY = 'redo';
	
	function redoItem() {
	  return {
	    key: KEY,
	    name: 'Redo',
	
	    callback: function callback() {
	      this.redo();
	    },
	    disabled: function disabled() {
	      return this.undoRedo && !this.undoRedo.isRedoAvailable();
	    }
	  };
	}
	
	/***/ }),
	/* 268 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = removeColumnItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'remove_col';
	
	function removeColumnItem() {
	  return {
	    key: KEY,
	    name: 'Remove column',
	
	    callback: function callback(key, selection) {
	      var amount = selection.end.col - selection.start.col + 1;
	
	      this.alter('remove_col', selection.start.col, amount, 'ContextMenu.removeColumn');
	    },
	    disabled: function disabled() {
	      var selected = (0, _utils.getValidSelection)(this);
	      var totalColumns = this.countCols();
	
	      return !selected || this.selection.selectedHeader.rows || this.selection.selectedHeader.corner || !this.isColumnModificationAllowed() || !totalColumns;
	    },
	    hidden: function hidden() {
	      return !this.getSettings().allowRemoveColumn;
	    }
	  };
	}
	
	/***/ }),
	/* 269 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = removeRowItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'remove_row';
	
	function removeRowItem() {
	  return {
	    key: KEY,
	    name: 'Remove row',
	
	    callback: function callback(key, selection) {
	      var amount = selection.end.row - selection.start.row + 1;
	
	      this.alter('remove_row', selection.start.row, amount, 'ContextMenu.removeRow');
	    },
	    disabled: function disabled() {
	      var selected = (0, _utils.getValidSelection)(this);
	      var totalRows = this.countRows();
	
	      return !selected || this.selection.selectedHeader.cols || this.selection.selectedHeader.corner || !totalRows;
	    },
	    hidden: function hidden() {
	      return !this.getSettings().allowRemoveRow;
	    }
	  };
	}
	
	/***/ }),
	/* 270 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = rowAboveItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'row_above';
	
	function rowAboveItem() {
	  return {
	    key: KEY,
	    name: 'Insert row above',
	
	    callback: function callback(key, selection) {
	      this.alter('insert_row', selection.start.row, 1, 'ContextMenu.rowAbove');
	    },
	    disabled: function disabled() {
	      var selected = (0, _utils.getValidSelection)(this);
	
	      return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows;
	    },
	    hidden: function hidden() {
	      return !this.getSettings().allowInsertRow;
	    }
	  };
	}
	
	/***/ }),
	/* 271 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.KEY = undefined;
	exports.default = rowBelowItem;
	
	var _utils = __webpack_require__(19);
	
	var KEY = exports.KEY = 'row_below';
	
	function rowBelowItem() {
	  return {
	    key: KEY,
	    name: 'Insert row below',
	
	    callback: function callback(key, selection) {
	      this.alter('insert_row', selection.end.row + 1, 1, 'ContextMenu.rowBelow');
	    },
	    disabled: function disabled() {
	      var selected = (0, _utils.getValidSelection)(this);
	
	      return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows;
	    },
	    hidden: function hidden() {
	      return !this.getSettings().allowInsertRow;
	    }
	  };
	}
	
	/***/ }),
	/* 272 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = undoItem;
	var KEY = exports.KEY = 'undo';
	
	function undoItem() {
	  return {
	    key: KEY,
	    name: 'Undo',
	
	    callback: function callback() {
	      this.undo();
	    },
	    disabled: function disabled() {
	      return this.undoRedo && !this.undoRedo.isUndoAvailable();
	    }
	  };
	}
	
	/***/ }),
	/* 273 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _core = __webpack_require__(82);
	
	var _core2 = _interopRequireDefault(_core);
	
	var _element = __webpack_require__(0);
	
	var _array = __webpack_require__(2);
	
	var _cursor = __webpack_require__(274);
	
	var _cursor2 = _interopRequireDefault(_cursor);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _object = __webpack_require__(1);
	
	var _function = __webpack_require__(35);
	
	var _utils = __webpack_require__(19);
	
	var _unicode = __webpack_require__(18);
	
	var _localHooks = __webpack_require__(87);
	
	var _localHooks2 = _interopRequireDefault(_localHooks);
	
	var _predefinedItems = __webpack_require__(88);
	
	var _event = __webpack_require__(10);
	
	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"); } }
	
	/**
	 * @class Menu
	 * @plugin ContextMenu
	 */
	var Menu = function () {
	  function Menu(hotInstance, options) {
	    _classCallCheck(this, Menu);
	
	    this.hot = hotInstance;
	    this.options = options || {
	      parent: null,
	      name: null,
	      className: '',
	      keepInViewport: true,
	      standalone: false
	    };
	    this.eventManager = new _eventManager2.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
	   */
	
	
	  _createClass(Menu, [{
	    key: 'registerEvents',
	    value: function registerEvents() {
	      var _this = this;
	
	      this.eventManager.addEventListener(document.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.
	     */
	
	  }, {
	    key: 'open',
	    value: function open() {
	      var _this2 = this;
	
	      this.container.removeAttribute('style');
	      this.container.style.display = 'block';
	
	      var delayedOpenSubMenu = (0, _function.debounce)(function (row) {
	        return _this2.openSubMenu(row);
	      }, 300);
	
	      var filteredItems = (0, _array.arrayFilter)(this.menuItems, function (item) {
	        return (0, _utils.isItemHidden)(item, _this2.hot);
	      });
	
	      filteredItems = (0, _utils.filterSeparators)(filteredItems, _predefinedItems.SEPARATOR);
	
	      var settings = {
	        data: filteredItems,
	        colHeaders: false,
	        colWidths: [200],
	        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, TD) {
	          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 _core2.default(this.container, settings);
	      this.hotMenu.addHook('afterInit', function () {
	        return _this2.onAfterInit();
	      });
	      this.hotMenu.addHook('afterSelection', function (r, c, r2, c2, preventScrolling) {
	        return _this2.onAfterSelection(r, c, r2, c2, preventScrolling);
	      });
	      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.getSelected()) {
	        return;
	      }
	      var selectedItem = this.hotMenu.getSourceDataAtRow(this.hotMenu.getSelected()[0]);
	
	      this.runLocalHooks('select', selectedItem, event);
	
	      if (selectedItem.isCommand === false || selectedItem.name === _predefinedItems.SEPARATOR) {
	        return;
	      }
	      var selRange = this.hot.getSelectedRange();
	      var normalizedSelection = selRange ? (0, _utils.normalizeSelection)(selRange) : {};
	      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 _cursor2.default(coords);
	
	      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 = 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 = top + 'px';
	    }
	
	    /**
	     * Set menu position on the right of cursor object.
	     *
	     * @param {Cursor} cursor `Cursor` object.
	     */
	
	  }, {
	    key: 'setPositionOnRightOfCursor',
	    value: function setPositionOnRightOfCursor(cursor) {
	      var left = void 0;
	
	      if (this.isSubMenu()) {
	        left = 1 + cursor.left + cursor.cellWidth;
	      } else {
	        left = this.offset.right + 1 + cursor.left;
	      }
	
	      this.container.style.left = 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)() + 4;
	
	      this.container.style.left = 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 = document.createElement('div');
	
	      var isSubMenu = function isSubMenu(item) {
	        return (0, _object.hasOwnProperty)(item, 'submenu');
	      };
	      var itemIsSeparator = function itemIsSeparator(item) {
	        return new RegExp(_predefinedItems.SEPARATOR, 'i').test(item.name);
	      };
	      var itemIsDisabled = function itemIsDisabled(item) {
	        return item.disabled === true || typeof item.disabled == 'function' && item.disabled.call(_this4.hot) === true;
	      };
	      var itemIsSelectionDisabled = function itemIsSelectionDisabled(item) {
	        return item.disableSelection;
	      };
	
	      if (typeof value === 'function') {
	        value = value.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, value));
	      } else {
	        (0, _element.fastInnerHTML)(wrapper, value);
	      }
	      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;
	
	      if (name) {
	        name = name.replace(/[^A-z0-9]/g, '_');
	        name = this.options.className + 'Sub_' + name;
	      }
	      var container = void 0;
	
	      if (name) {
	        container = document.querySelector('.' + this.options.className + '.' + name);
	      } else {
	        container = document.querySelector('.' + this.options.className);
	      }
	      if (!container) {
	        container = document.createElement('div');
	        (0, _element.addClass)(container, 'htMenu ' + this.options.className);
	
	        if (name) {
	          (0, _element.addClass)(container, name);
	        }
	        document.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.getSelected();
	      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 data = this.hotMenu.getSettings().data;
	      var hiderStyle = this.hotMenu.view.wt.wtTable.hider.style;
	      var holderStyle = this.hotMenu.view.wt.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 = currentHiderWidth + 22 + 'px';
	      holderStyle.height = 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.
	     */
	
	  }, {
	    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, document)) {
	        this.close(true);
	      }
	    }
	  }]);
	
	  return Menu;
	}();
	
	(0, _object.mixin)(Menu, _localHooks2.default);
	
	exports.default = Menu;
	
	/***/ }),
	/* 274 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _element = __webpack_require__(0);
	
	var _event = __webpack_require__(10);
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * Helper class for checking if element will fit at the desired side of cursor.
	 *
	 * @class Cursor
	 * @plugin ContextMenu
	 */
	var Cursor = function () {
	  function Cursor(object) {
	    _classCallCheck(this, Cursor);
	
	    var windowScrollTop = (0, _element.getWindowScrollTop)();
	    var windowScrollLeft = (0, _element.getWindowScrollLeft)();
	    var top = void 0,
	        topRelative = void 0;
	    var left = void 0,
	        leftRelative = void 0;
	    var cellHeight = void 0,
	        cellWidth = void 0;
	
	    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'`.
	   */
	
	
	  _createClass(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] : window.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] : window.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;
	}();
	
	exports.default = Cursor;
	
	/***/ }),
	/* 275 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 276 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _SheetClip = __webpack_require__(171);
	
	var _SheetClip2 = _interopRequireDefault(_SheetClip);
	
	var _src = __webpack_require__(12);
	
	var _element = __webpack_require__(0);
	
	var _array = __webpack_require__(2);
	
	var _number = __webpack_require__(6);
	
	var _plugins = __webpack_require__(5);
	
	var _textarea = __webpack_require__(277);
	
	var _textarea2 = _interopRequireDefault(_textarea);
	
	var _copy = __webpack_require__(278);
	
	var _copy2 = _interopRequireDefault(_copy);
	
	var _cut = __webpack_require__(279);
	
	var _cut2 = _interopRequireDefault(_cut);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _pasteEvent = __webpack_require__(280);
	
	var _pasteEvent2 = _interopRequireDefault(_pasteEvent);
	
	__webpack_require__(282);
	
	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; }
	
	_pluginHooks2.default.getSingleton().register('afterCopyLimit');
	_pluginHooks2.default.getSingleton().register('modifyCopyableRange');
	_pluginHooks2.default.getSingleton().register('beforeCut');
	_pluginHooks2.default.getSingleton().register('afterCut');
	_pluginHooks2.default.getSingleton().register('beforePaste');
	_pluginHooks2.default.getSingleton().register('afterPaste');
	_pluginHooks2.default.getSingleton().register('beforeCopy');
	_pluginHooks2.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.
	 *
	 * @example
	 * ```js
	 * ...
	 * copyPaste: true,
	 * ...
	 * ```
	 * @class CopyPaste
	 * @plugin CopyPaste
	 */
	
	var CopyPaste = function (_BasePlugin) {
	  _inherits(CopyPaste, _BasePlugin);
	
	  function CopyPaste(hotInstance) {
	    _classCallCheck(this, CopyPaste);
	
	    /**
	     * Event manager
	     *
	     * @type {EventManager}
	     */
	    var _this = _possibleConstructorReturn(this, (CopyPaste.__proto__ || Object.getPrototypeOf(CopyPaste)).call(this, hotInstance));
	
	    _this.eventManager = new _eventManager2.default(_this);
	    /**
	     * Maximum number of columns than can be copied to clipboard using <kbd>CTRL</kbd> + <kbd>C</kbd>.
	     *
	     * @private
	     * @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.
	     *
	     * @private
	     * @type {String}
	     * @default 'overwrite'
	     */
	    _this.pasteMode = 'overwrite';
	    /**
	     * Maximum number of rows than can be copied to clipboard using <kbd>CTRL</kbd> + <kbd>C</kbd>.
	     *
	     * @private
	     * @type {Number}
	     * @default 1000
	     */
	    _this.rowsLimit = ROWS_LIMIT;
	    /**
	     * The `textarea` element which is necessary to process copying, cutting off and pasting.
	     *
	     * @private
	     * @type {HTMLElement}
	     * @default undefined
	     */
	    _this.textarea = void 0;
	
	    privatePool.set(_this, {
	      isTriggeredByCopy: false,
	      isTriggeredByCut: false,
	      isBeginEditing: false,
	      isFragmentSelectionEnabled: false
	    });
	    return _this;
	  }
	
	  /**
	   * Check if plugin is enabled.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(CopyPaste, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return !!this.hot.getSettings().copyPaste;
	    }
	
	    /**
	     * Enable the plugin.
	     */
	
	  }, {
	    key: 'enablePlugin',
	    value: function enablePlugin() {
	      var _this2 = this;
	
	      if (this.enabled) {
	        return;
	      }
	      var settings = this.hot.getSettings();
	      var priv = privatePool.get(this);
	
	      this.textarea = _textarea2.default.getSingleton();
	      priv.isFragmentSelectionEnabled = settings.fragmentSelection;
	
	      if (_typeof(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('afterSelectionEnd', function () {
	        return _this2.onAfterSelectionEnd();
	      });
	
	      this.registerEvents();
	
	      _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Updates the plugin to use the latest options you have specified.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      this.disablePlugin();
	      this.enablePlugin();
	
	      _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      if (this.textarea) {
	        this.textarea.destroy();
	      }
	
	      _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Prepares copyable text from the cells selection in the invisible textarea.
	     *
	     * @function setCopyable
	     * @memberof CopyPaste#
	     */
	
	  }, {
	    key: 'setCopyableText',
	    value: function setCopyableText() {
	      var selRange = this.hot.getSelectedRange();
	
	      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);
	      }
	    }
	
	    /**
	     * Create copyable text releated to range objects.
	     *
	     * @since 0.19.0
	     * @param {Array} 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 _SheetClip2.default.stringify(dataSet);
	    }
	
	    /**
	     * Create copyable text releated to range objects.
	     *
	     * @since 0.31.1
	     * @param {Array} 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;
	    }
	
	    /**
	     * Copy action.
	     */
	
	  }, {
	    key: 'copy',
	    value: function copy() {
	      var priv = privatePool.get(this);
	
	      priv.isTriggeredByCopy = true;
	
	      this.textarea.select();
	      document.execCommand('copy');
	    }
	
	    /**
	     * Cut action.
	     */
	
	  }, {
	    key: 'cut',
	    value: function cut() {
	      var priv = privatePool.get(this);
	
	      priv.isTriggeredByCut = true;
	
	      this.textarea.select();
	      document.execCommand('cut');
	    }
	
	    /**
	     * Simulated paste action.
	     *
	     * @param {String} [value=''] New value, which should be `pasted`.
	     */
	
	  }, {
	    key: 'paste',
	    value: function paste() {
	      var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
	
	      var pasteData = new _pasteEvent2.default();
	      pasteData.clipboardData.setData('text/plain', value);
	
	      this.onPaste(pasteData);
	    }
	
	    /**
	     * Register event listeners.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'registerEvents',
	    value: function registerEvents() {
	      var _this5 = this;
	
	      this.eventManager.addEventListener(this.textarea.element, 'paste', function (event) {
	        return _this5.onPaste(event);
	      });
	      this.eventManager.addEventListener(this.textarea.element, 'cut', function (event) {
	        return _this5.onCut(event);
	      });
	      this.eventManager.addEventListener(this.textarea.element, 'copy', function (event) {
	        return _this5.onCopy(event);
	      });
	    }
	
	    /**
	     * `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) {
	        return;
	      }
	
	      this.setCopyableText();
	      priv.isTriggeredByCopy = false;
	
	      var rangedData = this.getRangedData(this.copyableRanges);
	      var allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges);
	      var value = '';
	
	      if (allowCopying) {
	        value = _SheetClip2.default.stringify(rangedData);
	
	        if (event && event.clipboardData) {
	          event.clipboardData.setData('text/plain', value);
	        } else if (typeof ClipboardEvent === 'undefined') {
	          window.clipboardData.setData('Text', value);
	        }
	
	        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) {
	        return;
	      }
	
	      this.setCopyableText();
	      priv.isTriggeredByCut = false;
	
	      var rangedData = this.getRangedData(this.copyableRanges);
	      var allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);
	      var value = void 0;
	
	      if (allowCuttingOut) {
	        value = _SheetClip2.default.stringify(rangedData);
	
	        if (event && event.clipboardData) {
	          event.clipboardData.setData('text/plain', value);
	        } else if (typeof ClipboardEvent === 'undefined') {
	          window.clipboardData.setData('Text', value);
	        }
	
	        this.hot.selection.empty();
	        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) {
	      var _this6 = this;
	
	      if (!this.hot.isListening()) {
	        return;
	      }
	      if (event && event.preventDefault) {
	        event.preventDefault();
	      }
	
	      var inputArray = void 0;
	
	      if (event && typeof event.clipboardData !== 'undefined') {
	        this.textarea.setValue(event.clipboardData.getData('text/plain'));
	      } else if (typeof ClipboardEvent === 'undefined' && typeof window.clipboardData !== 'undefined') {
	        this.textarea.setValue(window.clipboardData.getData('Text'));
	      }
	
	      inputArray = _SheetClip2.default.parse(this.textarea.getValue());
	      this.textarea.setValue(' ');
	
	      if (inputArray.length === 0) {
	        return;
	      }
	
	      var allowPasting = !!this.hot.runHooks('beforePaste', inputArray, this.copyableRanges);
	
	      if (!allowPasting) {
	        return;
	      }
	
	      var selected = this.hot.getSelected();
	      var coordsFrom = new _src.CellCoords(selected[0], selected[1]);
	      var coordsTo = new _src.CellCoords(selected[2], selected[3]);
	      var cellRange = new _src.CellRange(coordsFrom, coordsFrom, coordsTo);
	      var topLeftCorner = cellRange.getTopLeftCorner();
	      var bottomRightCorner = cellRange.getBottomRightCorner();
	      var areaStart = topLeftCorner;
	      var areaEnd = new _src.CellCoords(Math.max(bottomRightCorner.row, inputArray.length - 1 + topLeftCorner.row), Math.max(bottomRightCorner.col, inputArray[0].length - 1 + topLeftCorner.col));
	
	      var isSelRowAreaCoverInputValue = coordsTo.row - coordsFrom.row >= inputArray.length - 1;
	      var isSelColAreaCoverInputValue = coordsTo.col - coordsFrom.col >= inputArray[0].length - 1;
	
	      this.hot.addHookOnce('afterChange', function (changes) {
	        var changesLength = changes ? changes.length : 0;
	
	        if (changesLength) {
	          var offset = { row: 0, col: 0 };
	          var highestColumnIndex = -1;
	
	          (0, _array.arrayEach)(changes, function (change, index) {
	            var nextChange = changesLength > index + 1 ? changes[index + 1] : null;
	
	            if (nextChange) {
	              if (!isSelRowAreaCoverInputValue) {
	                offset.row += Math.max(nextChange[0] - change[0] - 1, 0);
	              }
	              if (!isSelColAreaCoverInputValue && change[1] > highestColumnIndex) {
	                highestColumnIndex = change[1];
	                offset.col += Math.max(nextChange[1] - change[1] - 1, 0);
	              }
	            }
	          });
	          _this6.hot.selectCell(areaStart.row, areaStart.col, areaEnd.row + offset.row, areaEnd.col + offset.col);
	        }
	      });
	
	      this.hot.populateFromArray(areaStart.row, areaStart.col, inputArray, areaEnd.row, areaEnd.col, 'CopyPaste.paste', this.pasteMode);
	      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, _copy2.default)(this), (0, _cut2.default)(this));
	    }
	
	    /**
	     * We have to keep focus on textarea element, to make possible use of the browser tools (copy, cut, paste).
	     *
	     * @private
	     */
	
	  }, {
	    key: 'onAfterSelectionEnd',
	    value: function onAfterSelectionEnd() {
	      var priv = privatePool.get(this);
	      var editor = this.hot.getActiveEditor();
	
	      if (editor && typeof editor.isOpened !== 'undefined' && editor.isOpened()) {
	        return;
	      }
	      if (priv.isFragmentSelectionEnabled && !this.textarea.isActive() && (0, _element.getSelectionText)()) {
	        return;
	      }
	
	      this.setCopyableText();
	      this.textarea.select();
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      if (this.textarea) {
	        this.textarea.destroy();
	      }
	
	      _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return CopyPaste;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('CopyPaste', CopyPaste);
	
	exports.default = CopyPaste;
	
	/***/ }),
	/* 277 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	/**
	 * @class Textarea
	 *
	 * @plugin CopyPaste
	 */
	var Textarea = function () {
	  _createClass(Textarea, null, [{
	    key: 'getSingleton',
	    value: function getSingleton() {
	      globalSingleton.append();
	
	      return globalSingleton;
	    }
	  }]);
	
	  function Textarea() {
	    _classCallCheck(this, Textarea);
	
	    /**
	     * Main textarea element.
	     *
	     * @type {HTMLElement}
	     */
	    this.element = void 0;
	    /**
	     * Store information about append to the document.body.
	     *
	     * @type {Boolean}
	     */
	    this.isAppended = false;
	    /**
	     * Reference counter.
	     *
	     * @type {Number}
	     */
	    this.refCounter = 0;
	  }
	
	  /**
	   * Apends textarea element to the `body`
	   */
	
	
	  _createClass(Textarea, [{
	    key: 'append',
	    value: function append() {
	      if (this.hasBeenDestroyed()) {
	        this.create();
	      }
	
	      this.refCounter++;
	
	      if (!this.isAppended && document.body) {
	        if (document.body) {
	          this.isAppended = true;
	          document.body.appendChild(this.element);
	        }
	      }
	    }
	
	    /**
	     * Prepares textarea element with proper attributes.
	     */
	
	  }, {
	    key: 'create',
	    value: function create() {
	      this.element = document.createElement('textarea');
	      this.element.id = 'HandsontableCopyPaste';
	      this.element.className = 'copyPaste';
	      this.element.tabIndex = -1;
	      this.element.autocomplete = 'off';
	      this.element.wrap = 'hard';
	      this.element.value = ' ';
	    }
	
	    /**
	     * Deselects textarea element if is active.
	     */
	
	  }, {
	    key: 'deselect',
	    value: function deselect() {
	      if (this.element === document.activeElement) {
	        document.activeElement.blur();
	      }
	    }
	
	    /**
	     * Destroy instance
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      this.refCounter--;
	      this.refCounter = this.refCounter < 0 ? 0 : this.refCounter;
	
	      if (this.hasBeenDestroyed() && this.element && this.element.parentNode) {
	        this.element.parentNode.removeChild(this.element);
	        this.element = null;
	        this.isAppended = false;
	      }
	    }
	
	    /**
	     * Getter for the element.
	     *
	     * @returns {String}
	     */
	
	  }, {
	    key: 'getValue',
	    value: function getValue() {
	      return this.element.value;
	    }
	
	    /**
	     * Check if instance has been destroyed
	     *
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'hasBeenDestroyed',
	    value: function hasBeenDestroyed() {
	      return this.refCounter < 1;
	    }
	
	    /**
	     * Check if the element is an active element in frame.
	     *
	     * @returns {Boolean}
	     */
	
	  }, {
	    key: 'isActive',
	    value: function isActive() {
	      return this.element === document.activeElement;
	    }
	
	    /**
	     * Sets focus on the element and select content.
	     */
	
	  }, {
	    key: 'select',
	    value: function select() {
	      this.element.focus();
	      this.element.select();
	    }
	
	    /**
	     * Setter for the element.
	     *
	     * @param {String} data Value which should be insert into the element.
	     */
	
	  }, {
	    key: 'setValue',
	    value: function setValue(data) {
	      this.element.value = data;
	    }
	  }]);
	
	  return Textarea;
	}();
	
	var globalSingleton = new Textarea();
	
	exports.default = Textarea;
	
	/***/ }),
	/* 278 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = copyItem;
	function copyItem(copyPastePlugin) {
	  return {
	    key: 'copy',
	    name: 'Copy',
	    callback: function callback() {
	      copyPastePlugin.copy();
	    },
	    disabled: function disabled() {
	      return !copyPastePlugin.hot.getSelected();
	    },
	
	    hidden: false
	  };
	}
	
	/***/ }),
	/* 279 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = cutItem;
	function cutItem(copyPastePlugin) {
	  return {
	    key: 'cut',
	    name: 'Cut',
	    callback: function callback() {
	      copyPastePlugin.cut();
	    },
	    disabled: function disabled() {
	      return !copyPastePlugin.hot.getSelected();
	    },
	
	    hidden: false
	  };
	}
	
	/***/ }),
	/* 280 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _clipboardData = __webpack_require__(281);
	
	var _clipboardData2 = _interopRequireDefault(_clipboardData);
	
	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"); } }
	
	var PasteEvent = function PasteEvent() {
	  _classCallCheck(this, PasteEvent);
	
	  this.clipboardData = new _clipboardData2.default();
	};
	
	exports.default = PasteEvent;
	
	/***/ }),
	/* 281 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	var ClipboardData = function () {
	  function ClipboardData() {
	    _classCallCheck(this, ClipboardData);
	
	    this.data = {};
	  }
	
	  _createClass(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;
	
	/***/ }),
	/* 282 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 283 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _plugins = __webpack_require__(5);
	
	var _object = __webpack_require__(1);
	
	var _src = __webpack_require__(12);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function CustomBorders() {}
	/** *
	 * Current instance (table where borders should be placed)
	 */
	var instance;
	
	/**
	 * 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: ''}
	 * ],
	 * ...
	 * ```
	 * @private
	 * @class CustomBorders
	 * @plugin CustomBorders
	 */
	
	/** *
	 * Check if plugin should be enabled.
	 */
	var checkEnable = function checkEnable(customBorders) {
	  if (typeof customBorders === 'boolean') {
	    if (customBorders === true) {
	      return true;
	    }
	  }
	  if ((typeof customBorders === 'undefined' ? 'undefined' : _typeof(customBorders)) === 'object') {
	    if (customBorders.length > 0) {
	      return true;
	    }
	  }
	
	  return false;
	};
	
	/** *
	 * Initialize plugin.
	 */
	var init = function init() {
	  if (checkEnable(this.getSettings().customBorders)) {
	    if (!this.customBorders) {
	      instance = this;
	      this.customBorders = new CustomBorders();
	    }
	  }
	};
	
	/** *
	 * Get index of border from the settings.
	 *
	 * @param {String} className
	 * @returns {Number}
	 */
	var getSettingIndex = function getSettingIndex(className) {
	  for (var i = 0; i < instance.view.wt.selections.length; i++) {
	    if (instance.view.wt.selections[i].settings.className == className) {
	      return i;
	    }
	  }
	
	  return -1;
	};
	
	/** *
	 * Insert WalkontableSelection instance into Walkontable settings.
	 *
	 * @param border
	 */
	var insertBorderIntoSettings = function insertBorderIntoSettings(border) {
	  var coordinates = {
	    row: border.row,
	    col: border.col
	  };
	  var selection = new _src.Selection(border, new _src.CellRange(coordinates, coordinates, coordinates));
	  var index = getSettingIndex(border.className);
	
	  if (index >= 0) {
	    instance.view.wt.selections[index] = selection;
	  } else {
	    instance.view.wt.selections.push(selection);
	  }
	};
	
	/** *
	 * Prepare borders from setting (single cell).
	 *
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 * @param borderObj
	 */
	var prepareBorderFromCustomAdded = function prepareBorderFromCustomAdded(row, col, borderObj) {
	  var border = createEmptyBorders(row, col);
	  border = extendDefaultBorder(border, borderObj);
	  this.setCellMeta(row, col, 'borders', border);
	
	  insertBorderIntoSettings(border);
	};
	
	/** *
	 * Prepare borders from setting (object).
	 *
	 * @param {Object} rowObj
	 */
	var prepareBorderFromCustomAddedRange = function prepareBorderFromCustomAddedRange(rowObj) {
	  var range = rowObj.range;
	
	  for (var row = range.from.row; row <= range.to.row; row++) {
	    for (var col = range.from.col; col <= range.to.col; col++) {
	      var border = createEmptyBorders(row, col);
	      var add = 0;
	
	      if (row == range.from.row) {
	        add++;
	
	        if ((0, _object.hasOwnProperty)(rowObj, 'top')) {
	          border.top = rowObj.top;
	        }
	      }
	
	      if (row == range.to.row) {
	        add++;
	
	        if ((0, _object.hasOwnProperty)(rowObj, 'bottom')) {
	          border.bottom = rowObj.bottom;
	        }
	      }
	
	      if (col == range.from.col) {
	        add++;
	
	        if ((0, _object.hasOwnProperty)(rowObj, 'left')) {
	          border.left = rowObj.left;
	        }
	      }
	
	      if (col == range.to.col) {
	        add++;
	
	        if ((0, _object.hasOwnProperty)(rowObj, 'right')) {
	          border.right = rowObj.right;
	        }
	      }
	
	      if (add > 0) {
	        this.setCellMeta(row, col, 'borders', border);
	        insertBorderIntoSettings(border);
	      }
	    }
	  }
	};
	
	/** *
	 * Create separated class name for borders for each cell.
	 *
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 * @returns {String}
	 */
	var createClassName = function createClassName(row, col) {
	  return 'border_row' + row + 'col' + col;
	};
	
	/** *
	 * Create default single border for each position (top/right/bottom/left).
	 *
	 * @returns {Object} `{{width: number, color: string}}`
	 */
	var createDefaultCustomBorder = function createDefaultCustomBorder() {
	  return {
	    width: 1,
	    color: '#000'
	  };
	};
	
	/** *
	 * Create default object for empty border.
	 *
	 * @returns {Object} `{{hide: boolean}}`
	 */
	var createSingleEmptyBorder = function createSingleEmptyBorder() {
	  return {
	    hide: true
	  };
	};
	
	/** *
	 * Create default Handsontable border object.
	 *
	 * @returns {Object} `{{width: number, color: string, cornerVisible: boolean}}`
	 */
	var createDefaultHtBorder = 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} `{{className: *, border: *, row: *, col: *, top: {hide: boolean}, right: {hide: boolean}, bottom: {hide: boolean}, left: {hide: boolean}}}`
	 */
	var createEmptyBorders = function createEmptyBorders(row, col) {
	  return {
	    className: createClassName(row, col),
	    border: createDefaultHtBorder(),
	    row: row,
	    col: col,
	    top: createSingleEmptyBorder(),
	    right: createSingleEmptyBorder(),
	    bottom: createSingleEmptyBorder(),
	    left: createSingleEmptyBorder()
	  };
	};
	
	var extendDefaultBorder = function extendDefaultBorder(defaultBorder, customBorder) {
	  if ((0, _object.hasOwnProperty)(customBorder, 'border')) {
	    defaultBorder.border = customBorder.border;
	  }
	
	  if ((0, _object.hasOwnProperty)(customBorder, 'top')) {
	    defaultBorder.top = customBorder.top;
	  }
	
	  if ((0, _object.hasOwnProperty)(customBorder, 'right')) {
	    defaultBorder.right = customBorder.right;
	  }
	
	  if ((0, _object.hasOwnProperty)(customBorder, 'bottom')) {
	    defaultBorder.bottom = customBorder.bottom;
	  }
	
	  if ((0, _object.hasOwnProperty)(customBorder, 'left')) {
	    defaultBorder.left = customBorder.left;
	  }
	
	  return defaultBorder;
	};
	
	/**
	 * Remove borders divs from DOM.
	 *
	 * @param borderClassName
	 */
	var removeBordersFromDom = function removeBordersFromDom(borderClassName) {
	  var borders = document.querySelectorAll('.' + borderClassName);
	
	  for (var i = 0; i < borders.length; i++) {
	    if (borders[i]) {
	      if (borders[i].nodeName != 'TD') {
	        var parent = borders[i].parentNode;
	
	        if (parent.parentNode) {
	          parent.parentNode.removeChild(parent);
	        }
	      }
	    }
	  }
	};
	
	/** *
	 * Remove border (triggered from context menu).
	 *
	 * @param {Number} row Visual row index.
	 * @param {Number} col Visual column index.
	 */
	var removeAllBorders = function removeAllBorders(row, col) {
	  var borderClassName = createClassName(row, col);
	  removeBordersFromDom(borderClassName);
	  this.removeCellMeta(row, col, 'borders');
	};
	
	/** *
	 * Set borders for each cell re. to border position
	 *
	 * @param row Visual row index.
	 * @param col Visual column index.
	 * @param place
	 * @param remove
	 */
	var setBorder = function setBorder(row, col, place, remove) {
	
	  var bordersMeta = this.getCellMeta(row, col).borders;
	
	  if (!bordersMeta || bordersMeta.border == undefined) {
	    bordersMeta = createEmptyBorders(row, col);
	  }
	
	  if (remove) {
	    bordersMeta[place] = createSingleEmptyBorder();
	  } else {
	    bordersMeta[place] = createDefaultCustomBorder();
	  }
	
	  this.setCellMeta(row, col, 'borders', bordersMeta);
	
	  var borderClassName = createClassName(row, col);
	  removeBordersFromDom(borderClassName);
	  insertBorderIntoSettings(bordersMeta);
	
	  this.render();
	};
	
	/** *
	 * Prepare borders based on cell and border position
	 *
	 * @param range
	 * @param place
	 * @param remove
	 */
	var prepareBorder = function prepareBorder(range, place, remove) {
	
	  if (range.from.row == range.to.row && range.from.col == range.to.col) {
	    if (place == 'noBorders') {
	      removeAllBorders.call(this, range.from.row, range.from.col);
	    } else {
	      setBorder.call(this, range.from.row, range.from.col, place, remove);
	    }
	  } else {
	    switch (place) {
	      case 'noBorders':
	        for (var column = range.from.col; column <= range.to.col; column++) {
	          for (var row = range.from.row; row <= range.to.row; row++) {
	            removeAllBorders.call(this, row, column);
	          }
	        }
	        break;
	      case 'top':
	        for (var topCol = range.from.col; topCol <= range.to.col; topCol++) {
	          setBorder.call(this, range.from.row, topCol, place, remove);
	        }
	        break;
	      case 'right':
	        for (var rowRight = range.from.row; rowRight <= range.to.row; rowRight++) {
	          setBorder.call(this, rowRight, range.to.col, place);
	        }
	        break;
	      case 'bottom':
	        for (var bottomCol = range.from.col; bottomCol <= range.to.col; bottomCol++) {
	          setBorder.call(this, range.to.row, bottomCol, place);
	        }
	        break;
	      case 'left':
	        for (var rowLeft = range.from.row; rowLeft <= range.to.row; rowLeft++) {
	          setBorder.call(this, rowLeft, range.from.col, place);
	        }
	        break;
	      default:
	        break;
	    }
	  }
	};
	
	/** *
	 * Check if selection has border by className
	 *
	 * @param hot
	 * @param direction
	 */
	var checkSelectionBorders = function checkSelectionBorders(hot, direction) {
	  var atLeastOneHasBorder = false;
	
	  hot.getSelectedRange().forAll(function (r, c) {
	    var metaBorders = hot.getCellMeta(r, c).borders;
	
	    if (metaBorders) {
	      if (direction) {
	        if (!(0, _object.hasOwnProperty)(metaBorders[direction], 'hide')) {
	          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}
	 */
	var markSelected = function markSelected(label) {
	  return '<span class="selected">' + String.fromCharCode(10003) + '</span>' + label; // workaround for https://github.com/handsontable/handsontable/issues/1946
	};
	
	/** *
	 * Add border options to context menu
	 *
	 * @param defaultOptions
	 */
	var addBordersOptionsToContextMenu = function addBordersOptionsToContextMenu(defaultOptions) {
	  if (!this.getSettings().customBorders) {
	    return;
	  }
	
	  defaultOptions.items.push({
	    name: '---------'
	  });
	  defaultOptions.items.push({
	    key: 'borders',
	    name: 'Borders',
	    disabled: function disabled() {
	      return this.selection.selectedHeader.corner;
	    },
	
	    submenu: {
	      items: [{
	        key: 'borders:top',
	        name: function name() {
	          var label = 'Top';
	          var hasBorder = checkSelectionBorders(this, 'top');
	          if (hasBorder) {
	            label = markSelected(label);
	          }
	
	          return label;
	        },
	        callback: function callback() {
	          var hasBorder = checkSelectionBorders(this, 'top');
	          prepareBorder.call(this, this.getSelectedRange(), 'top', hasBorder);
	        }
	      }, {
	        key: 'borders:right',
	        name: function name() {
	          var label = 'Right';
	          var hasBorder = checkSelectionBorders(this, 'right');
	          if (hasBorder) {
	            label = markSelected(label);
	          }
	          return label;
	        },
	        callback: function callback() {
	          var hasBorder = checkSelectionBorders(this, 'right');
	          prepareBorder.call(this, this.getSelectedRange(), 'right', hasBorder);
	        }
	      }, {
	        key: 'borders:bottom',
	        name: function name() {
	          var label = 'Bottom';
	          var hasBorder = checkSelectionBorders(this, 'bottom');
	          if (hasBorder) {
	            label = markSelected(label);
	          }
	          return label;
	        },
	        callback: function callback() {
	          var hasBorder = checkSelectionBorders(this, 'bottom');
	          prepareBorder.call(this, this.getSelectedRange(), 'bottom', hasBorder);
	        }
	      }, {
	        key: 'borders:left',
	        name: function name() {
	          var label = 'Left';
	          var hasBorder = checkSelectionBorders(this, 'left');
	          if (hasBorder) {
	            label = markSelected(label);
	          }
	
	          return label;
	        },
	        callback: function callback() {
	          var hasBorder = checkSelectionBorders(this, 'left');
	          prepareBorder.call(this, this.getSelectedRange(), 'left', hasBorder);
	        }
	      }, {
	        key: 'borders:no_borders',
	        name: 'Remove border(s)',
	        callback: function callback() {
	          prepareBorder.call(this, this.getSelectedRange(), 'noBorders');
	        },
	        disabled: function disabled() {
	          return !checkSelectionBorders(this);
	        }
	      }]
	    }
	  });
	};
	
	_pluginHooks2.default.getSingleton().add('beforeInit', init);
	_pluginHooks2.default.getSingleton().add('afterContextMenuDefaultOptions', addBordersOptionsToContextMenu);
	_pluginHooks2.default.getSingleton().add('afterInit', function () {
	  var customBorders = this.getSettings().customBorders;
	
	  if (customBorders) {
	    for (var i = 0; i < customBorders.length; i++) {
	      if (customBorders[i].range) {
	        prepareBorderFromCustomAddedRange.call(this, customBorders[i]);
	      } else {
	        prepareBorderFromCustomAdded.call(this, customBorders[i].row, customBorders[i].col, customBorders[i]);
	      }
	    }
	
	    this.render();
	    this.view.wt.draw(true);
	  }
	});
	
	/***/ }),
	/* 284 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _plugins = __webpack_require__(5);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * @description
	 * Plugin used to scroll Handsontable by selecting a cell and dragging outside of the visible viewport.
	 *
	 * @private
	 * @class DragToScroll
	 * @plugin DragToScroll
	 */
	function DragToScroll() {
	  this.boundaries = null;
	  this.callback = null;
	}
	
	/**
	 * @param boundaries {Object} compatible with getBoundingClientRect
	 */
	DragToScroll.prototype.setBoundaries = function (boundaries) {
	  this.boundaries = boundaries;
	};
	
	/**
	 * @param callback {Function}
	 */
	DragToScroll.prototype.setCallback = function (callback) {
	  this.callback = callback;
	};
	
	/**
	 * Check if mouse position (x, y) is outside of the viewport
	 * @param x
	 * @param y
	 */
	DragToScroll.prototype.check = function (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);
	};
	
	var dragToScroll;
	var instance;
	
	var setupListening = function setupListening(instance) {
	  instance.dragToScrollListening = false;
	  var scrollHandler = instance.view.wt.wtTable.holder; // native scroll
	  dragToScroll = new DragToScroll();
	
	  if (scrollHandler === window) {
	    // not much we can do currently
	    return;
	  }
	
	  dragToScroll.setBoundaries(scrollHandler.getBoundingClientRect());
	  dragToScroll.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;
	    }
	  });
	
	  instance.dragToScrollListening = true;
	};
	
	_pluginHooks2.default.getSingleton().add('afterInit', function () {
	  var instance = this;
	  var eventManager = new _eventManager2.default(this);
	
	  eventManager.addEventListener(document, 'mouseup', function () {
	    instance.dragToScrollListening = false;
	  });
	
	  eventManager.addEventListener(document, 'mousemove', function (event) {
	    if (instance.dragToScrollListening) {
	      dragToScroll.check(event.clientX, event.clientY);
	    }
	  });
	});
	
	_pluginHooks2.default.getSingleton().add('afterDestroy', function () {
	  new _eventManager2.default(this).clear();
	});
	
	_pluginHooks2.default.getSingleton().add('afterOnCellMouseDown', function () {
	  setupListening(this);
	});
	
	_pluginHooks2.default.getSingleton().add('afterOnCellCornerMouseDown', function () {
	  setupListening(this);
	});
	
	exports.default = DragToScroll;
	
	/***/ }),
	/* 285 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _plugins = __webpack_require__(5);
	
	var _array = __webpack_require__(2);
	
	var _freezeColumn = __webpack_require__(286);
	
	var _freezeColumn2 = _interopRequireDefault(_freezeColumn);
	
	var _unfreezeColumn = __webpack_require__(287);
	
	var _unfreezeColumn2 = _interopRequireDefault(_unfreezeColumn);
	
	__webpack_require__(288);
	
	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; }
	
	var privatePool = new WeakMap();
	/**
	 * This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu.
	 * You can turn it on by setting a `manualColumnFreeze` property to `true`.
	 *
	 * @plugin ManualColumnFreeze
	 * @dependencies ManualColumnMove
	 */
	
	var ManualColumnFreeze = function (_BasePlugin) {
	  _inherits(ManualColumnFreeze, _BasePlugin);
	
	  function ManualColumnFreeze(hotInstance) {
	    _classCallCheck(this, ManualColumnFreeze);
	
	    var _this = _possibleConstructorReturn(this, (ManualColumnFreeze.__proto__ || Object.getPrototypeOf(ManualColumnFreeze)).call(this, hotInstance));
	
	    privatePool.set(_this, {
	      moveByFreeze: false,
	      afterFirstUse: false
	    });
	    /**
	     * Original column positions
	     *
	     * @type {Array}
	     */
	    _this.frozenColumnsBasePositions = [];
	    /**
	     * Reference to the `ManualColumnMove` plugin.
	     */
	    _this.manualColumnMovePlugin = void 0;
	    return _this;
	  }
	
	  /**
	   * Check if the plugin is enabled in the Handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ManualColumnFreeze, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return !!this.hot.getSettings().manualColumnFreeze;
	    }
	
	    /**
	     * Enable plugin 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);
	      });
	
	      _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      var priv = privatePool.get(this);
	
	      priv.afterFirstUse = false;
	      priv.moveByFreeze = false;
	
	      _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Updates the plugin to use the latest options you have specified.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      this.disablePlugin();
	      this.enablePlugin();
	
	      _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Freeze 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++);
	    }
	
	    /**
	     * Unfreeze 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--;
	
	      this.getMovePlugin().moveColumn(column, returnCol + 1);
	    }
	
	    /**
	     * Get 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 = void 0;
	
	      if (this.frozenColumnsBasePositions[column] == null) {
	        initialCol = movePlugin.columnsMapper.getValueByIndex(column);
	
	        while (j < initialCol) {
	          i++;
	          j = movePlugin.columnsMapper.getValueByIndex(i);
	        }
	      } else {
	        initialCol = this.frozenColumnsBasePositions[column];
	        this.frozenColumnsBasePositions[column] = void 0;
	
	        while (j <= initialCol) {
	          i++;
	          j = movePlugin.columnsMapper.getValueByIndex(i);
	        }
	        i = j;
	      }
	
	      return i - 1;
	    }
	    /**
	     * Add the manualColumnFreeze context menu entries.
	     *
	     * @private
	     * @param {Object} options Context menu options.
	     */
	
	  }, {
	    key: 'addContextMenuEntry',
	    value: function addContextMenuEntry(options) {
	      options.items.push({ name: '---------' }, (0, _freezeColumn2.default)(this), (0, _unfreezeColumn2.default)(this));
	    }
	
	    /**
	     * Enabling `manualColumnMove` plugin on `afterInit` hook.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'onAfterInit',
	    value: function onAfterInit() {
	      if (!this.getMovePlugin().isEnabled()) {
	        this.getMovePlugin().enablePlugin();
	      }
	    }
	
	    /**
	     * Prevent 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, index, array) {
	            if (value < frozenLen) {
	              disallowMoving = true;
	              return false;
	            }
	          });
	        }
	
	        if (disallowMoving) {
	          return false;
	        }
	      }
	
	      if (priv.moveByFreeze) {
	        priv.moveByFreeze = false;
	      }
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return ManualColumnFreeze;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('manualColumnFreeze', ManualColumnFreeze);
	
	exports.default = ManualColumnFreeze;
	
	/***/ }),
	/* 286 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = freezeColumnItem;
	function freezeColumnItem(manualColumnFreezePlugin) {
	  return {
	    key: 'freeze_column',
	    name: 'Freeze this column',
	    callback: function callback() {
	      var selectedColumn = this.getSelectedRange().from.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.from.col !== selection.to.col || selection.from.col <= this.getSettings().fixedColumnsLeft - 1) {
	        hide = true;
	      }
	
	      return hide;
	    }
	  };
	}
	
	/***/ }),
	/* 287 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	exports.default = unfreezeColumnItem;
	function unfreezeColumnItem(manualColumnFreezePlugin) {
	  return {
	    key: 'unfreeze_column',
	    name: 'Unfreeze this column',
	    callback: function callback() {
	      var selectedColumn = this.getSelectedRange().from.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.from.col !== selection.to.col || selection.from.col >= this.getSettings().fixedColumnsLeft) {
	        hide = true;
	      }
	
	      return hide;
	    }
	  };
	}
	
	/***/ }),
	/* 288 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 289 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _array = __webpack_require__(2);
	
	var _element = __webpack_require__(0);
	
	var _number = __webpack_require__(6);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _plugins = __webpack_require__(5);
	
	var _columnsMapper = __webpack_require__(290);
	
	var _columnsMapper2 = _interopRequireDefault(_columnsMapper);
	
	var _backlight = __webpack_require__(291);
	
	var _backlight2 = _interopRequireDefault(_backlight);
	
	var _guideline = __webpack_require__(292);
	
	var _guideline2 = _interopRequireDefault(_guideline);
	
	var _src = __webpack_require__(12);
	
	__webpack_require__(293);
	
	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; }
	
	_pluginHooks2.default.getSingleton().register('beforeColumnMove');
	_pluginHooks2.default.getSingleton().register('afterColumnMove');
	_pluginHooks2.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.
	 *
	 * 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.
	 *
	 * UI components:
	 * - backlight - highlight of selected columns.
	 * - guideline - line which shows where rows has been moved.
	 *
	 * @class ManualColumnMove
	 * @plugin ManualColumnMove
	 */
	
	var ManualColumnMove = function (_BasePlugin) {
	  _inherits(ManualColumnMove, _BasePlugin);
	
	  function ManualColumnMove(hotInstance) {
	    _classCallCheck(this, ManualColumnMove);
	
	    /**
	     * Set up WeakMap of plugin to sharing private parameters;
	     */
	    var _this = _possibleConstructorReturn(this, (ManualColumnMove.__proto__ || Object.getPrototypeOf(ManualColumnMove)).call(this, hotInstance));
	
	    privatePool.set(_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.
	     *
	     * @type {Array}
	     */
	    _this.removedColumns = [];
	    /**
	     * Object containing visual row indexes mapped to data source indexes.
	     *
	     * @type {RowsMapper}
	     */
	    _this.columnsMapper = new _columnsMapper2.default(_this);
	    /**
	     * Event Manager object.
	     *
	     * @type {Object}
	     */
	    _this.eventManager = new _eventManager2.default(_this);
	    /**
	     * Backlight UI object.
	     *
	     * @type {Object}
	     */
	    _this.backlight = new _backlight2.default(hotInstance);
	    /**
	     * Guideline UI object.
	     *
	     * @type {Object}
	     */
	    _this.guideline = new _guideline2.default(hotInstance);
	    return _this;
	  }
	
	  /**
	   * Check if plugin is enabled.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ManualColumnMove, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return !!this.hot.getSettings().manualColumnMove;
	    }
	
	    /**
	     * Enable the plugin.
	     */
	
	  }, {
	    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);
	
	      _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Updates the plugin to use the latest options you have specified.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      this.disablePlugin();
	      this.enablePlugin();
	
	      this.onAfterPluginsInitialized();
	
	      _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin 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();
	
	      _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Move 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.
	     */
	
	  }, {
	    key: 'moveColumn',
	    value: function moveColumn(column, target) {
	      this.moveColumns([column], target);
	    }
	
	    /**
	     * Move 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.
	     */
	
	  }, {
	    key: 'moveColumns',
	    value: function moveColumns(columns, target) {
	      var _this3 = this;
	
	      var priv = privatePool.get(this);
	      var beforeColumnHook = this.hot.runHooks('beforeColumnMove', columns, 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', columns, 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) {
	      var selection = this.hot.selection;
	      var lastRowIndex = this.hot.countRows() - 1;
	
	      selection.setRangeStartOnly(new _src.CellCoords(0, startColumn));
	      selection.setRangeEnd(new _src.CellCoords(lastRowIndex, endColumn), false);
	    }
	
	    /**
	     * Get 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;
	    }
	
	    /**
	     * Load 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();
	      }
	    }
	
	    /**
	     * Check 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;
	    }
	
	    /**
	     * Save the manual column positions to the persistent state.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'persistentStateSave',
	    value: function persistentStateSave() {
	      this.hot.runHooks('persistentStateSave', 'manualColumnMove', this.columnsMapper._arrayMap);
	    }
	
	    /**
	     * Load the manual column positions from the persistent state.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'persistentStateLoad',
	    value: function persistentStateLoad() {
	      var storedState = {};
	
	      this.hot.runHooks('persistentStateLoad', 'manualColumnMove', storedState);
	
	      if (storedState.value) {
	        this.columnsMapper._arrayMap = storedState.value;
	      }
	    }
	
	    /**
	     * Prepare 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;
	    }
	
	    /**
	     * Update 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++;
	        }
	      }
	
	      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) {
	          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) {
	          this.hot.scrollViewportTo(void 0, firstVisible - 1);
	        }
	      }
	
	      if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns) {
	        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);
	      }
	    }
	
	    /**
	     * Bind the events used by the plugin.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'registerEvents',
	    value: function registerEvents() {
	      var _this4 = this;
	
	      this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) {
	        return _this4.onMouseMove(event);
	      });
	      this.eventManager.addEventListener(document.documentElement, 'mouseup', function () {
	        return _this4.onMouseUp();
	      });
	    }
	
	    /**
	     * Unbind the events used by the plugin.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'unregisterEvents',
	    value: function unregisterEvents() {
	      this.eventManager.clear();
	    }
	
	    /**
	     * Change 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.selectedHeader.cols;
	      var selection = this.hot.getSelectedRange();
	      var priv = privatePool.get(this);
	      var isSortingElement = event.realTarget.className.indexOf('columnSorting') > -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.getSelectedRange();
	      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.selectedHeader.cols) {
	        (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) {
	      if (source !== this.pluginName) {
	        // ugly fix for try to insert new, needed columns after pasting data
	        var columnInMapper = this.columnsMapper.getValueByIndex(column);
	        column = columnInMapper === null ? column : columnInMapper;
	      }
	
	      return column;
	    }
	
	    /**
	     * '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();
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      this.backlight.destroy();
	      this.guideline.destroy();
	
	      _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return ManualColumnMove;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('ManualColumnMove', ManualColumnMove);
	
	exports.default = ManualColumnMove;
	
	/***/ }),
	/* 290 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _arrayMapper = __webpack_require__(176);
	
	var _arrayMapper2 = _interopRequireDefault(_arrayMapper);
	
	var _array = __webpack_require__(2);
	
	var _object = __webpack_require__(1);
	
	var _number = __webpack_require__(6);
	
	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"); } }
	
	/**
	 * @class ColumnsMapper
	 * @plugin ManualColumnMove
	 */
	var ColumnsMapper = function () {
	  function ColumnsMapper(manualColumnMove) {
	    _classCallCheck(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.
	   */
	
	
	  _createClass(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, _arrayMapper2.default);
	
	exports.default = ColumnsMapper;
	
	/***/ }),
	/* 291 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(177);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _element = __webpack_require__(0);
	
	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; }
	
	var CSS_CLASSNAME = 'ht__manualColumnMove--backlight';
	
	/**
	 * @class BacklightUI
	 * @util
	 */
	
	var BacklightUI = function (_BaseUI) {
	  _inherits(BacklightUI, _BaseUI);
	
	  function BacklightUI() {
	    _classCallCheck(this, BacklightUI);
	
	    return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments));
	  }
	
	  _createClass(BacklightUI, [{
	    key: 'build',
	
	    /**
	     * Custom className on build process.
	     */
	    value: function build() {
	      _get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this);
	
	      (0, _element.addClass)(this._element, CSS_CLASSNAME);
	    }
	  }]);
	
	  return BacklightUI;
	}(_base2.default);
	
	exports.default = BacklightUI;
	
	/***/ }),
	/* 292 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(177);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _element = __webpack_require__(0);
	
	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; }
	
	var CSS_CLASSNAME = 'ht__manualColumnMove--guideline';
	
	/**
	 * @class GuidelineUI
	 * @util
	 */
	
	var GuidelineUI = function (_BaseUI) {
	  _inherits(GuidelineUI, _BaseUI);
	
	  function GuidelineUI() {
	    _classCallCheck(this, GuidelineUI);
	
	    return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments));
	  }
	
	  _createClass(GuidelineUI, [{
	    key: 'build',
	
	    /**
	     * Custom className on build process.
	     */
	    value: function build() {
	      _get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this);
	
	      (0, _element.addClass)(this._element, CSS_CLASSNAME);
	    }
	  }]);
	
	  return GuidelineUI;
	}(_base2.default);
	
	exports.default = GuidelineUI;
	
	/***/ }),
	/* 293 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 294 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _element = __webpack_require__(0);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _event = __webpack_require__(10);
	
	var _array = __webpack_require__(2);
	
	var _number = __webpack_require__(6);
	
	var _plugins = __webpack_require__(5);
	
	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; }
	
	// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js
	
	/**
	 * @description
	 * ManualColumnResize Plugin.
	 *
	 * Has 2 UI components:
	 * - 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 = function (_BasePlugin) {
	  _inherits(ManualColumnResize, _BasePlugin);
	
	  function ManualColumnResize(hotInstance) {
	    _classCallCheck(this, ManualColumnResize);
	
	    var _this = _possibleConstructorReturn(this, (ManualColumnResize.__proto__ || Object.getPrototypeOf(ManualColumnResize)).call(this, hotInstance));
	
	    _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 = document.createElement('DIV');
	    _this.guide = document.createElement('DIV');
	    _this.eventManager = new _eventManager2.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;
	  }
	
	  /**
	   * Check if the plugin is enabled in the handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ManualColumnResize, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return this.hot.getSettings().manualColumnResize;
	    }
	
	    /**
	     * Enable plugin 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();
	
	      _get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Updates the plugin to use the latest options you have specified.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      var initialColumnWidth = this.hot.getSettings().manualColumnResize;
	
	      if (Array.isArray(initialColumnWidth)) {
	        this.manualColumnWidths = initialColumnWidth;
	      } else if (!initialColumnWidth) {
	        this.manualColumnWidths = [];
	      }
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      _get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Save the current sizes using the persistentState plugin.
	     */
	
	  }, {
	    key: 'saveManualColumnWidths',
	    value: function saveManualColumnWidths() {
	      this.hot.runHooks('persistentStateSave', 'manualColumnWidths', this.manualColumnWidths);
	    }
	
	    /**
	     * Load the previously saved sizes using the persistentState plugin.
	     *
	     * @returns {Array}
	     */
	
	  }, {
	    key: 'loadManualColumnWidths',
	    value: function loadManualColumnWidths() {
	      var storedState = {};
	
	      this.hot.runHooks('persistentStateLoad', 'manualColumnWidths', storedState);
	
	      return storedState.value;
	    }
	
	    /**
	     * Set the resize handle position.
	     *
	     * @param {HTMLCellElement} TH TH HTML element.
	     */
	
	  }, {
	    key: 'setupHandlePosition',
	    value: function setupHandlePosition(TH) {
	      var _this3 = this;
	
	      if (!TH.parentNode) {
	        return false;
	      }
	
	      this.currentTH = TH;
	
	      var col = this.hot.view.wt.wtTable.getCoords(TH).col; // getCoords returns CellCoords
	      var headerHeight = (0, _element.outerHeight)(this.currentTH);
	
	      if (col >= 0) {
	        // if not col header
	        var box = this.currentTH.getBoundingClientRect();
	
	        this.currentCol = col;
	        this.selectedCols = [];
	
	        if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.cols) {
	          var _hot$getSelectedRange = this.hot.getSelectedRange(),
	              from = _hot$getSelectedRange.from,
	              to = _hot$getSelectedRange.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 = box.left - 6;
	        this.startWidth = parseInt(box.width, 10);
	        this.handle.style.top = box.top + 'px';
	        this.handle.style.left = this.startOffset + this.startWidth + 'px';
	        this.handle.style.height = headerHeight + 'px';
	        this.hot.rootElement.appendChild(this.handle);
	      }
	    }
	
	    /**
	     * Refresh the resize handle position.
	     */
	
	  }, {
	    key: 'refreshHandlePosition',
	    value: function refreshHandlePosition() {
	      this.handle.style.left = this.startOffset + this.currentWidth + 'px';
	    }
	
	    /**
	     * Set the resize guide position.
	     */
	
	  }, {
	    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 = handleBottomPosition + 'px';
	      this.guide.style.left = this.handle.style.left;
	      this.guide.style.height = maximumVisibleElementHeight - handleHeight + 'px';
	      this.hot.rootElement.appendChild(this.guide);
	    }
	
	    /**
	     * Refresh the resize guide position.
	     */
	
	  }, {
	    key: 'refreshGuidePosition',
	    value: function refreshGuidePosition() {
	      this.guide.style.left = this.handle.style.left;
	    }
	
	    /**
	     * Hide both the resize handle and resize guide.
	     */
	
	  }, {
	    key: 'hideHandleAndGuide',
	    value: function hideHandleAndGuide() {
	      (0, _element.removeClass)(this.handle, 'active');
	      (0, _element.removeClass)(this.guide, 'active');
	    }
	
	    /**
	     * Check if provided element is considered a column header.
	     *
	     * @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;
	    }
	
	    /**
	     * Get the TH element from the provided element.
	     *
	     * @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
	     */
	
	  }, {
	    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} e
	     */
	
	  }, {
	    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++;
	
	        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} e
	     */
	
	  }, {
	    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
	     * @param {MouseEvent} e
	     */
	
	  }, {
	    key: 'onMouseUp',
	    value: function onMouseUp(event) {
	      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);
	
	        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);
	      }
	    }
	
	    /**
	     * Bind the mouse events.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'bindEvents',
	    value: function bindEvents() {
	      var _this8 = this;
	
	      this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) {
	        return _this8.onMouseOver(e);
	      });
	      this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) {
	        return _this8.onMouseDown(e);
	      });
	      this.eventManager.addEventListener(window, 'mousemove', function (e) {
	        return _this8.onMouseMove(e);
	      });
	      this.eventManager.addEventListener(window, 'mouseup', function (e) {
	        return _this8.onMouseUp(e);
	      });
	    }
	
	    /**
	     * Cache the current column width.
	     *
	     * @param {Number} column Visual column index.
	     * @param {Number} width Column width.
	     * @returns {Number}
	     */
	
	  }, {
	    key: 'setManualSize',
	    value: function setManualSize(column, width) {
	      width = 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.
	       */
	      column = this.hot.runHooks('modifyCol', column);
	
	      this.manualColumnWidths[column] = width;
	
	      return width;
	    }
	
	    /**
	     * Clear cache for the current column index.
	     *
	     * @param {Number} column Visual column index.
	     */
	
	  }, {
	    key: 'clearManualSize',
	    value: function clearManualSize(column) {
	      column = this.hot.runHooks('modifyCol', column);
	
	      this.manualColumnWidths[column] = void 0;
	    }
	
	    /**
	     * Modify 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) {
	      if (this.enabled) {
	        column = this.hot.runHooks('modifyCol', column);
	
	        if (this.hot.getSettings().manualColumnResize && this.manualColumnWidths[column]) {
	          return this.manualColumnWidths[column];
	        }
	      }
	
	      return width;
	    }
	
	    /**
	     * Modify 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
	     * @param {Number} currentColumn Index of the resized column.
	     * @param {Number} newSize Calculated new column width.
	     * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
	     */
	
	  }, {
	    key: 'onBeforeColumnResize',
	    value: function onBeforeColumnResize() {
	      // clear the header height cache information
	      this.hot.view.wt.wtViewport.hasOversizedColumnHeadersMarked = {};
	    }
	  }]);
	
	  return ManualColumnResize;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('manualColumnResize', ManualColumnResize);
	
	exports.default = ManualColumnResize;
	
	/***/ }),
	/* 295 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _array = __webpack_require__(2);
	
	var _element = __webpack_require__(0);
	
	var _number = __webpack_require__(6);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _plugins = __webpack_require__(5);
	
	var _rowsMapper = __webpack_require__(296);
	
	var _rowsMapper2 = _interopRequireDefault(_rowsMapper);
	
	var _backlight = __webpack_require__(297);
	
	var _backlight2 = _interopRequireDefault(_backlight);
	
	var _guideline = __webpack_require__(298);
	
	var _guideline2 = _interopRequireDefault(_guideline);
	
	var _src = __webpack_require__(12);
	
	__webpack_require__(299);
	
	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; }
	
	_pluginHooks2.default.getSingleton().register('beforeRowMove');
	_pluginHooks2.default.getSingleton().register('afterRowMove');
	_pluginHooks2.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.
	 *
	 * 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.
	 *
	 * UI components:
	 * - backlight - highlight of selected rows.
	 * - guideline - line which shows where rows has been moved.
	 *
	 * @class ManualRowMove
	 * @plugin ManualRowMove
	 */
	
	var ManualRowMove = function (_BasePlugin) {
	  _inherits(ManualRowMove, _BasePlugin);
	
	  function ManualRowMove(hotInstance) {
	    _classCallCheck(this, ManualRowMove);
	
	    /**
	     * Set up WeakMap of plugin to sharing private parameters;
	     */
	    var _this = _possibleConstructorReturn(this, (ManualRowMove.__proto__ || Object.getPrototypeOf(ManualRowMove)).call(this, hotInstance));
	
	    privatePool.set(_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.
	     *
	     * @type {Array}
	     */
	    _this.removedRows = [];
	    /**
	     * Object containing visual row indexes mapped to data source indexes.
	     *
	     * @type {RowsMapper}
	     */
	    _this.rowsMapper = new _rowsMapper2.default(_this);
	    /**
	     * Event Manager object.
	     *
	     * @type {Object}
	     */
	    _this.eventManager = new _eventManager2.default(_this);
	    /**
	     * Backlight UI object.
	     *
	     * @type {Object}
	     */
	    _this.backlight = new _backlight2.default(hotInstance);
	    /**
	     * Guideline UI object.
	     *
	     * @type {Object}
	     */
	    _this.guideline = new _guideline2.default(hotInstance);
	    return _this;
	  }
	
	  /**
	   * Check if plugin is enabled.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ManualRowMove, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return !!this.hot.getSettings().manualRowMove;
	    }
	
	    /**
	     * Enable the plugin.
	     */
	
	  }, {
	    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);
	
	      _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Updates the plugin to use the latest options you have specified.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      this.disablePlugin();
	      this.enablePlugin();
	
	      this.onAfterPluginsInitialized();
	
	      _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin 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();
	
	      _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Move 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.
	     */
	
	  }, {
	    key: 'moveRow',
	    value: function moveRow(row, target) {
	      this.moveRows([row], target);
	    }
	
	    /**
	     * Move 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.
	     */
	
	  }, {
	    key: 'moveRows',
	    value: function moveRows(rows, target) {
	      var _this3 = this;
	
	      var priv = privatePool.get(this);
	      var beforeMoveHook = this.hot.runHooks('beforeRowMove', rows, 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', rows, 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) {
	      var selection = this.hot.selection;
	      var lastColIndex = this.hot.countCols() - 1;
	
	      selection.setRangeStartOnly(new _src.CellCoords(startRow, 0));
	      selection.setRangeEnd(new _src.CellCoords(endRow, lastColIndex), false);
	    }
	
	    /**
	     * Get 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;
	    }
	
	    /**
	     * Load 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);
	        }
	      }
	    }
	
	    /**
	     * Check 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;
	    }
	
	    /**
	     * Check 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;
	    }
	
	    /**
	     * Save the manual row positions to the persistent state.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'persistentStateSave',
	    value: function persistentStateSave() {
	      this.hot.runHooks('persistentStateSave', 'manualRowMove', this.rowsMapper._arrayMap);
	    }
	
	    /**
	     * Load the manual row positions from the persistent state.
	     *
	     * @private
	     * @returns {Array} Stored state.
	     */
	
	  }, {
	    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.getSelectedRange();
	      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);
	      }
	    }
	
	    /**
	     * Bind the events used by the plugin.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'registerEvents',
	    value: function registerEvents() {
	      var _this4 = this;
	
	      this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) {
	        return _this4.onMouseMove(event);
	      });
	      this.eventManager.addEventListener(document.documentElement, 'mouseup', function () {
	        return _this4.onMouseUp();
	      });
	    }
	
	    /**
	     * Unbind 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;
	    }
	
	    /**
	     * Change 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 wtTable = this.hot.view.wt.wtTable;
	      var isHeaderSelection = this.hot.selection.selectedHeader.rows;
	      var selection = this.hot.getSelectedRange();
	      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 + this.hot.view.wt.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.getSelectedRange();
	      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.selectedHeader.rows) {
	        (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) {
	      if (source !== this.pluginName) {
	        var rowInMapper = this.rowsMapper.getValueByIndex(row);
	        row = rowInMapper === null ? row : rowInMapper;
	      }
	
	      return row;
	    }
	
	    /**
	     * '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();
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      this.backlight.destroy();
	      this.guideline.destroy();
	
	      _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'destroy', this).call(this);
	    }
	  }]);
	
	  return ManualRowMove;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('ManualRowMove', ManualRowMove);
	
	exports.default = ManualRowMove;
	
	/***/ }),
	/* 296 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _arrayMapper = __webpack_require__(176);
	
	var _arrayMapper2 = _interopRequireDefault(_arrayMapper);
	
	var _array = __webpack_require__(2);
	
	var _object = __webpack_require__(1);
	
	var _number = __webpack_require__(6);
	
	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"); } }
	
	/**
	 * @class RowsMapper
	 * @plugin ManualRowMove
	 */
	var RowsMapper = function () {
	  function RowsMapper(manualRowMove) {
	    _classCallCheck(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.
	   */
	
	
	  _createClass(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, _arrayMapper2.default);
	
	exports.default = RowsMapper;
	
	/***/ }),
	/* 297 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(178);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _element = __webpack_require__(0);
	
	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; }
	
	var CSS_CLASSNAME = 'ht__manualRowMove--backlight';
	
	/**
	 * @class BacklightUI
	 * @util
	 */
	
	var BacklightUI = function (_BaseUI) {
	  _inherits(BacklightUI, _BaseUI);
	
	  function BacklightUI() {
	    _classCallCheck(this, BacklightUI);
	
	    return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments));
	  }
	
	  _createClass(BacklightUI, [{
	    key: 'build',
	
	    /**
	     * Custom className on build process.
	     */
	    value: function build() {
	      _get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this);
	
	      (0, _element.addClass)(this._element, CSS_CLASSNAME);
	    }
	  }]);
	
	  return BacklightUI;
	}(_base2.default);
	
	exports.default = BacklightUI;
	
	/***/ }),
	/* 298 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(178);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _element = __webpack_require__(0);
	
	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; }
	
	var CSS_CLASSNAME = 'ht__manualRowMove--guideline';
	
	/**
	 * @class GuidelineUI
	 * @util
	 */
	
	var GuidelineUI = function (_BaseUI) {
	  _inherits(GuidelineUI, _BaseUI);
	
	  function GuidelineUI() {
	    _classCallCheck(this, GuidelineUI);
	
	    return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments));
	  }
	
	  _createClass(GuidelineUI, [{
	    key: 'build',
	
	    /**
	     * Custom className on build process.
	     */
	    value: function build() {
	      _get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this);
	
	      (0, _element.addClass)(this._element, CSS_CLASSNAME);
	    }
	  }]);
	
	  return GuidelineUI;
	}(_base2.default);
	
	exports.default = GuidelineUI;
	
	/***/ }),
	/* 299 */
	/***/ (function(module, exports) {
	
	// removed by extract-text-webpack-plugin
	
	/***/ }),
	/* 300 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _element = __webpack_require__(0);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _event = __webpack_require__(10);
	
	var _array = __webpack_require__(2);
	
	var _number = __webpack_require__(6);
	
	var _plugins = __webpack_require__(5);
	
	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; }
	
	// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js
	
	/**
	 * @description
	 * ManualRowResize Plugin.
	 *
	 * Has 2 UI components:
	 * - 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 = function (_BasePlugin) {
	  _inherits(ManualRowResize, _BasePlugin);
	
	  function ManualRowResize(hotInstance) {
	    _classCallCheck(this, ManualRowResize);
	
	    var _this = _possibleConstructorReturn(this, (ManualRowResize.__proto__ || Object.getPrototypeOf(ManualRowResize)).call(this, hotInstance));
	
	    _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 = document.createElement('DIV');
	    _this.guide = document.createElement('DIV');
	    _this.eventManager = new _eventManager2.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;
	  }
	
	  /**
	   * Check if the plugin is enabled in the handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ManualRowResize, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return this.hot.getSettings().manualRowResize;
	    }
	
	    /**
	     * Enable plugin 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();
	
	      _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Updates the plugin to use the latest options you have specified.
	     */
	
	  }, {
	    key: 'updatePlugin',
	    value: function updatePlugin() {
	      var initialRowHeights = this.hot.getSettings().manualRowResize;
	
	      if (Array.isArray(initialRowHeights)) {
	        this.manualRowHeights = initialRowHeights;
	      } else if (!initialRowHeights) {
	        this.manualRowHeights = [];
	      }
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'disablePlugin', this).call(this);
	    }
	
	    /**
	     * Save the current sizes using the persistentState plugin.
	     */
	
	  }, {
	    key: 'saveManualRowHeights',
	    value: function saveManualRowHeights() {
	      this.hot.runHooks('persistentStateSave', 'manualRowHeights', this.manualRowHeights);
	    }
	
	    /**
	     * Load the previously saved sizes using the persistentState plugin.
	     *
	     * @returns {Array}
	     */
	
	  }, {
	    key: 'loadManualRowHeights',
	    value: function loadManualRowHeights() {
	      var storedState = {};
	
	      this.hot.runHooks('persistentStateLoad', 'manualRowHeights', storedState);
	
	      return storedState.value;
	    }
	
	    /**
	     * Set the resize handle position.
	     *
	     * @param {HTMLCellElement} TH TH HTML element.
	     */
	
	  }, {
	    key: 'setupHandlePosition',
	    value: function setupHandlePosition(TH) {
	      var _this3 = this;
	
	      this.currentTH = TH;
	      var row = this.hot.view.wt.wtTable.getCoords(TH).row; // getCoords returns CellCoords
	      var headerWidth = (0, _element.outerWidth)(this.currentTH);
	
	      if (row >= 0) {
	        // if not col header
	        var box = this.currentTH.getBoundingClientRect();
	
	        this.currentRow = row;
	        this.selectedRows = [];
	
	        if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.rows) {
	          var _hot$getSelectedRange = this.hot.getSelectedRange(),
	              from = _hot$getSelectedRange.from,
	              to = _hot$getSelectedRange.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 = box.top - 6;
	        this.startHeight = parseInt(box.height, 10);
	        this.handle.style.left = box.left + 'px';
	        this.handle.style.top = this.startOffset + this.startHeight + 'px';
	        this.handle.style.width = headerWidth + 'px';
	        this.hot.rootElement.appendChild(this.handle);
	      }
	    }
	
	    /**
	     * Refresh the resize handle position.
	     */
	
	  }, {
	    key: 'refreshHandlePosition',
	    value: function refreshHandlePosition() {
	      this.handle.style.top = this.startOffset + this.currentHeight + 'px';
	    }
	
	    /**
	     * Set the resize guide position.
	     */
	
	  }, {
	    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 = handleRightPosition + 'px';
	      this.guide.style.width = maximumVisibleElementWidth - handleWidth + 'px';
	      this.hot.rootElement.appendChild(this.guide);
	    }
	
	    /**
	     * Refresh the resize guide position.
	     */
	
	  }, {
	    key: 'refreshGuidePosition',
	    value: function refreshGuidePosition() {
	      this.guide.style.top = this.handle.style.top;
	    }
	
	    /**
	     * Hide both the resize handle and resize guide.
	     */
	
	  }, {
	    key: 'hideHandleAndGuide',
	    value: function hideHandleAndGuide() {
	      (0, _element.removeClass)(this.handle, 'active');
	      (0, _element.removeClass)(this.guide, 'active');
	    }
	
	    /**
	     * Check if provided element is considered as a row header.
	     *
	     * @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;
	    }
	
	    /**
	     * Get the TH element from the provided element.
	     *
	     * @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
	     */
	
	  }, {
	    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++;
	
	        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
	     * @param {MouseEvent} event
	     */
	
	  }, {
	    key: 'onMouseUp',
	    value: function onMouseUp(event) {
	      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);
	      };
	      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);
	      }
	    }
	
	    /**
	     * Bind the mouse events.
	     *
	     * @private
	     */
	
	  }, {
	    key: 'bindEvents',
	    value: function bindEvents() {
	      var _this8 = this;
	
	      this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) {
	        return _this8.onMouseOver(e);
	      });
	      this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) {
	        return _this8.onMouseDown(e);
	      });
	      this.eventManager.addEventListener(window, 'mousemove', function (e) {
	        return _this8.onMouseMove(e);
	      });
	      this.eventManager.addEventListener(window, 'mouseup', function (e) {
	        return _this8.onMouseUp(e);
	      });
	    }
	
	    /**
	     * Cache the current row height.
	     *
	     * @param {Number} row Visual row index.
	     * @param {Number} height Row height.
	     * @returns {Number}
	     */
	
	  }, {
	    key: 'setManualSize',
	    value: function setManualSize(row, height) {
	      row = this.hot.runHooks('modifyRow', row);
	      this.manualRowHeights[row] = height;
	
	      return height;
	    }
	
	    /**
	     * Modify the provided row height, based on the plugin settings.
	     *
	     * @private
	     * @param {Number} height Row height.
	     * @param {Number} row Visual row index.
	     * @returns {Number}
	     */
	
	  }, {
	    key: 'onModifyRowHeight',
	    value: function onModifyRowHeight(height, row) {
	      if (this.enabled) {
	        var autoRowSizePlugin = this.hot.getPlugin('autoRowSize');
	        var autoRowHeightResult = autoRowSizePlugin ? autoRowSizePlugin.heights[row] : null;
	
	        row = this.hot.runHooks('modifyRow', row);
	
	        var manualRowHeight = this.manualRowHeights[row];
	
	        if (manualRowHeight !== void 0 && (manualRowHeight === autoRowHeightResult || manualRowHeight > (height || 0))) {
	          return manualRowHeight;
	        }
	      }
	
	      return height;
	    }
	  }]);
	
	  return ManualRowResize;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('manualRowResize', ManualRowResize);
	
	exports.default = ManualRowResize;
	
	/***/ }),
	/* 301 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _plugins = __webpack_require__(5);
	
	var _event = __webpack_require__(10);
	
	var _src = __webpack_require__(12);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function CellInfoCollection() {
	  var collection = [];
	
	  collection.getInfo = function (row, col) {
	    for (var i = 0, ilen = this.length; i < ilen; i++) {
	      if (this[i].row <= row && this[i].row + this[i].rowspan - 1 >= row && this[i].col <= col && this[i].col + this[i].colspan - 1 >= col) {
	        return this[i];
	      }
	    }
	  };
	
	  collection.setInfo = function (info) {
	    for (var i = 0, ilen = this.length; i < ilen; i++) {
	      if (this[i].row === info.row && this[i].col === info.col) {
	        this[i] = info;
	        return;
	      }
	    }
	    this.push(info);
	  };
	
	  collection.removeInfo = function (row, col) {
	    for (var i = 0, ilen = this.length; i < ilen; i++) {
	      if (this[i].row === row && this[i].col === col) {
	        this.splice(i, 1);
	        break;
	      }
	    }
	  };
	
	  return collection;
	}
	
	/**
	 * Plugin used to merge cells in Handsontable.
	 *
	 * @private
	 * @plugin MergeCells
	 * @class MergeCells
	 */
	function MergeCells(mergeCellsSetting) {
	  this.mergedCellInfoCollection = new CellInfoCollection();
	
	  if (Array.isArray(mergeCellsSetting)) {
	    for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) {
	      this.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]);
	    }
	  }
	}
	
	/**
	 * @param cellRange (CellRange)
	 */
	MergeCells.prototype.canMergeRange = function (cellRange) {
	  // is more than one cell selected
	  return !cellRange.isSingle();
	};
	
	MergeCells.prototype.mergeRange = function (cellRange) {
	  if (!this.canMergeRange(cellRange)) {
	    return;
	  }
	
	  // normalize top left corner
	  var topLeft = cellRange.getTopLeftCorner();
	  var bottomRight = cellRange.getBottomRightCorner();
	
	  var mergeParent = {};
	  mergeParent.row = topLeft.row;
	  mergeParent.col = topLeft.col;
	  // TD has rowspan == 1 by default. rowspan == 2 means spread over 2 cells
	  mergeParent.rowspan = bottomRight.row - topLeft.row + 1;
	  mergeParent.colspan = bottomRight.col - topLeft.col + 1;
	  this.mergedCellInfoCollection.setInfo(mergeParent);
	};
	
	MergeCells.prototype.mergeOrUnmergeSelection = function (cellRange) {
	  var info = this.mergedCellInfoCollection.getInfo(cellRange.from.row, cellRange.from.col);
	  if (info) {
	    // unmerge
	    this.unmergeSelection(cellRange.from);
	  } else {
	    // merge
	    this.mergeSelection(cellRange);
	  }
	};
	
	MergeCells.prototype.mergeSelection = function (cellRange) {
	  this.mergeRange(cellRange);
	};
	
	MergeCells.prototype.unmergeSelection = function (cellRange) {
	  var info = this.mergedCellInfoCollection.getInfo(cellRange.row, cellRange.col);
	  this.mergedCellInfoCollection.removeInfo(info.row, info.col);
	};
	
	MergeCells.prototype.applySpanProperties = function (TD, row, col) {
	  var info = this.mergedCellInfoCollection.getInfo(row, col);
	
	  if (info) {
	    if (info.row === row && info.col === col) {
	      TD.setAttribute('rowspan', info.rowspan);
	      TD.setAttribute('colspan', info.colspan);
	    } else {
	      TD.removeAttribute('rowspan');
	      TD.removeAttribute('colspan');
	
	      TD.style.display = 'none';
	    }
	  } else {
	    TD.removeAttribute('rowspan');
	    TD.removeAttribute('colspan');
	  }
	};
	
	MergeCells.prototype.modifyTransform = function (hook, currentSelectedRange, delta) {
	  var sameRowspan = function sameRowspan(merged, coords) {
	    if (coords.row >= merged.row && coords.row <= merged.row + merged.rowspan - 1) {
	      return true;
	    }
	    return false;
	  },
	      sameColspan = function sameColspan(merged, coords) {
	    if (coords.col >= merged.col && coords.col <= merged.col + merged.colspan - 1) {
	      return true;
	    }
	    return false;
	  },
	      getNextPosition = function getNextPosition(newDelta) {
	    return new _src.CellCoords(currentSelectedRange.to.row + newDelta.row, currentSelectedRange.to.col + newDelta.col);
	  };
	
	  var newDelta = {
	    row: delta.row,
	    col: delta.col
	  };
	
	  if (hook == 'modifyTransformStart') {
	    /* eslint-disable block-scoped-var */
	    var nextPosition;
	
	    if (!this.lastDesiredCoords) {
	      this.lastDesiredCoords = new _src.CellCoords(null, null);
	    }
	    var currentPosition = new _src.CellCoords(currentSelectedRange.highlight.row, currentSelectedRange.highlight.col),
	
	    // if current position's parent is a merged range, returns it
	    mergedParent = this.mergedCellInfoCollection.getInfo(currentPosition.row, currentPosition.col),
	        currentRangeContainsMerge; // if current range contains a merged range
	
	    for (var i = 0, mergesLength = this.mergedCellInfoCollection.length; i < mergesLength; i++) {
	      var range = this.mergedCellInfoCollection[i];
	      range = new _src.CellCoords(range.row + range.rowspan - 1, range.col + range.colspan - 1);
	      if (currentSelectedRange.includes(range)) {
	        currentRangeContainsMerge = true;
	        break;
	      }
	    }
	
	    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(this.lastDesiredCoords)) {
	        this.lastDesiredCoords = new _src.CellCoords(null, null); // reset outdated version of lastDesiredCoords
	      }
	
	      newDelta.row = this.lastDesiredCoords.row ? this.lastDesiredCoords.row - currentPosition.row : newDelta.row;
	      newDelta.col = this.lastDesiredCoords.col ? this.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(currentSelectedRange.highlight.row + newDelta.row, currentSelectedRange.highlight.col + newDelta.col);
	
	    var nextParentIsMerged = this.mergedCellInfoCollection.getInfo(nextPosition.row, nextPosition.col);
	
	    if (nextParentIsMerged) {
	      // skipping the invisible cells in the merge range
	      this.lastDesiredCoords = nextPosition;
	      newDelta = {
	        row: nextParentIsMerged.row - currentPosition.row,
	        col: nextParentIsMerged.col - currentPosition.col
	      };
	    }
	  } else if (hook == 'modifyTransformEnd') {
	    for (var _i = 0, _mergesLength = this.mergedCellInfoCollection.length; _i < _mergesLength; _i++) {
	      var currentMerge = this.mergedCellInfoCollection[_i];
	      var _mergeTopLeft = new _src.CellCoords(currentMerge.row, currentMerge.col);
	      var _mergeBottomRight = new _src.CellCoords(currentMerge.row + currentMerge.rowspan - 1, currentMerge.col + currentMerge.colspan - 1);
	      var mergedRange = new _src.CellRange(_mergeTopLeft, _mergeTopLeft, _mergeBottomRight);
	      var sharedBorders = currentSelectedRange.getBordersSharedWith(mergedRange);
	
	      if (mergedRange.isEqual(currentSelectedRange)) {
	        // only the merged range is selected
	        currentSelectedRange.setDirection('NW-SE');
	      } else if (sharedBorders.length > 0) {
	        var mergeHighlighted = currentSelectedRange.highlight.isEqual(mergedRange.from);
	
	        if (sharedBorders.indexOf('top') > -1) {
	          // if range shares a border with the merged section, change range direction accordingly
	          if (currentSelectedRange.to.isSouthEastOf(mergedRange.from) && mergeHighlighted) {
	            currentSelectedRange.setDirection('NW-SE');
	          } else if (currentSelectedRange.to.isSouthWestOf(mergedRange.from) && mergeHighlighted) {
	            currentSelectedRange.setDirection('NE-SW');
	          }
	        } else if (sharedBorders.indexOf('bottom') > -1) {
	          if (currentSelectedRange.to.isNorthEastOf(mergedRange.from) && mergeHighlighted) {
	            currentSelectedRange.setDirection('SW-NE');
	          } else if (currentSelectedRange.to.isNorthWestOf(mergedRange.from) && mergeHighlighted) {
	            currentSelectedRange.setDirection('SE-NW');
	          }
	        }
	      }
	
	      nextPosition = getNextPosition(newDelta);
	      var withinRowspan = sameRowspan(currentMerge, nextPosition),
	          withinColspan = sameColspan(currentMerge, nextPosition);
	
	      if (currentSelectedRange.includesRange(mergedRange) && (mergedRange.includes(nextPosition) || withinRowspan || withinColspan)) {
	        // if next step overlaps a merged range, jump past it
	        if (withinRowspan) {
	          if (newDelta.row < 0) {
	            newDelta.row -= currentMerge.rowspan - 1;
	          } else if (newDelta.row > 0) {
	            newDelta.row += currentMerge.rowspan - 1;
	          }
	        }
	        if (withinColspan) {
	          if (newDelta.col < 0) {
	            newDelta.col -= currentMerge.colspan - 1;
	          } else if (newDelta.col > 0) {
	            newDelta.col += currentMerge.colspan - 1;
	          }
	        }
	      }
	    }
	  }
	
	  if (newDelta.row !== 0) {
	    delta.row = newDelta.row;
	  }
	  if (newDelta.col !== 0) {
	    delta.col = newDelta.col;
	  }
	};
	
	MergeCells.prototype.shiftCollection = function (direction, index, count) {
	  var shiftVector = [0, 0];
	
	  switch (direction) {
	    case 'right':
	      shiftVector[0] += 1;
	
	      break;
	    case 'left':
	      shiftVector[0] -= 1;
	
	      break;
	    case 'down':
	      shiftVector[1] += 1;
	
	      break;
	    case 'up':
	      shiftVector[1] -= 1;
	
	      break;
	    default:
	      break;
	  }
	
	  for (var i = 0; i < this.mergedCellInfoCollection.length; i++) {
	    var currentMerge = this.mergedCellInfoCollection[i];
	
	    if (direction === 'right' || direction === 'left') {
	      if (index <= currentMerge.col) {
	        currentMerge.col += shiftVector[0];
	      }
	    } else if (index <= currentMerge.row) {
	      currentMerge.row += shiftVector[1];
	    }
	  }
	};
	
	var beforeInit = function beforeInit() {
	  var instance = this;
	  var mergeCellsSetting = instance.getSettings().mergeCells;
	
	  if (mergeCellsSetting) {
	    if (!instance.mergeCells) {
	      instance.mergeCells = new MergeCells(mergeCellsSetting);
	    }
	  }
	};
	
	var afterInit = function afterInit() {
	  var instance = this;
	  if (instance.mergeCells) {
	    /**
	     * Monkey patch Table.prototype.getCell to return TD for merged cell parent if asked for TD of a cell that is
	     * invisible due to the merge. This is not the cleanest solution but there is a test case for it (merged cells scroll) so feel free to refactor it!
	     */
	    instance.view.wt.wtTable.getCell = function (coords) {
	      if (instance.getSettings().mergeCells) {
	        var mergeParent = instance.mergeCells.mergedCellInfoCollection.getInfo(coords.row, coords.col);
	        if (mergeParent) {
	          coords = mergeParent;
	        }
	      }
	      return _src.Table.prototype.getCell.call(this, coords);
	    };
	  }
	};
	
	var afterUpdateSettings = function afterUpdateSettings() {
	  var instance = this;
	  var mergeCellsSetting = instance.getSettings().mergeCells;
	
	  if (mergeCellsSetting) {
	    if (instance.mergeCells) {
	      instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection();
	
	      if (Array.isArray(mergeCellsSetting)) {
	        for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) {
	          instance.mergeCells.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]);
	        }
	      }
	    } else {
	      instance.mergeCells = new MergeCells(mergeCellsSetting);
	    }
	  } else if (instance.mergeCells) {
	    // it doesn't actually turn off the plugin, just resets the settings. Need to refactor.
	    instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection();
	  }
	};
	
	var onBeforeKeyDown = function onBeforeKeyDown(event) {
	  if (!this.mergeCells) {
	    return;
	  }
	
	  var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
	
	  if (ctrlDown) {
	    if (event.keyCode === 77) {
	      // CTRL + M
	      this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange());
	      this.render();
	      (0, _event.stopImmediatePropagation)(event);
	    }
	  }
	};
	
	var addMergeActionsToContextMenu = function addMergeActionsToContextMenu(defaultOptions) {
	  if (!this.getSettings().mergeCells) {
	    return;
	  }
	
	  defaultOptions.items.push({ name: '---------' });
	  defaultOptions.items.push({
	    key: 'mergeCells',
	    name: function name() {
	      var sel = this.getSelected();
	      var info = this.mergeCells.mergedCellInfoCollection.getInfo(sel[0], sel[1]);
	      if (info) {
	        return 'Unmerge cells';
	      }
	      return 'Merge cells';
	    },
	    callback: function callback() {
	      this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange());
	      this.render();
	    },
	    disabled: function disabled() {
	      return this.selection.selectedHeader.corner;
	    }
	  });
	};
	
	var afterRenderer = function afterRenderer(TD, row, col, prop, value, cellProperties) {
	  if (this.mergeCells) {
	    this.mergeCells.applySpanProperties(TD, row, col);
	  }
	};
	
	var modifyTransformFactory = function modifyTransformFactory(hook) {
	  return function (delta) {
	    var mergeCellsSetting = this.getSettings().mergeCells;
	    if (mergeCellsSetting) {
	      var currentSelectedRange = this.getSelectedRange();
	      this.mergeCells.modifyTransform(hook, currentSelectedRange, delta);
	
	      if (hook === 'modifyTransformEnd') {
	        // sanitize "from" (core.js will sanitize to)
	        var totalRows = this.countRows();
	        var totalCols = this.countCols();
	        if (currentSelectedRange.from.row < 0) {
	          currentSelectedRange.from.row = 0;
	        } else if (currentSelectedRange.from.row > 0 && currentSelectedRange.from.row >= totalRows) {
	          currentSelectedRange.from.row = currentSelectedRange.from - 1;
	        }
	
	        if (currentSelectedRange.from.col < 0) {
	          currentSelectedRange.from.col = 0;
	        } else if (currentSelectedRange.from.col > 0 && currentSelectedRange.from.col >= totalCols) {
	          currentSelectedRange.from.col = totalCols - 1;
	        }
	      }
	    }
	  };
	};
	
	/**
	 * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell
	 * @param coords
	 */
	var beforeSetRangeEnd = function beforeSetRangeEnd(coords) {
	
	  this.lastDesiredCoords = null; // unset lastDesiredCoords when selection is changed with mouse
	  var mergeCellsSetting = this.getSettings().mergeCells;
	  if (mergeCellsSetting) {
	    var selRange = this.getSelectedRange();
	    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;
	    do {
	      rangeExpanded = false;
	
	      for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) {
	        var cellInfo = this.mergeCells.mergedCellInfoCollection[i];
	        var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col);
	        var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1);
	
	        var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight);
	        if (selRange.expandByRange(mergedCellRange)) {
	          coords.row = selRange.to.row;
	          coords.col = selRange.to.col;
	
	          rangeExpanded = true;
	        }
	      }
	    } while (rangeExpanded);
	  }
	};
	
	/**
	 * Returns correct coordinates for merged start / end cells in selection for area borders
	 * @param corners
	 * @param className
	 */
	var beforeDrawAreaBorders = function beforeDrawAreaBorders(corners, className) {
	  if (className && className == 'area') {
	    var mergeCellsSetting = this.getSettings().mergeCells;
	    if (mergeCellsSetting) {
	      var selRange = this.getSelectedRange();
	      var startRange = new _src.CellRange(selRange.from, selRange.from, selRange.from);
	      var stopRange = new _src.CellRange(selRange.to, selRange.to, selRange.to);
	
	      for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) {
	        var cellInfo = this.mergeCells.mergedCellInfoCollection[i];
	        var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col);
	        var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1);
	        var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight);
	
	        if (startRange.expandByRange(mergedCellRange)) {
	          corners[0] = startRange.from.row;
	          corners[1] = startRange.from.col;
	        }
	
	        if (stopRange.expandByRange(mergedCellRange)) {
	          corners[2] = stopRange.from.row;
	          corners[3] = stopRange.from.col;
	        }
	      }
	    }
	  }
	};
	
	var afterGetCellMeta = function afterGetCellMeta(row, col, cellProperties) {
	  var mergeCellsSetting = this.getSettings().mergeCells;
	  if (mergeCellsSetting) {
	    var mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(row, col);
	    if (mergeParent && (mergeParent.row != row || mergeParent.col != col)) {
	      cellProperties.copyable = false;
	    }
	  }
	};
	
	var afterViewportRowCalculatorOverride = function afterViewportRowCalculatorOverride(calc) {
	  var mergeCellsSetting = this.getSettings().mergeCells;
	  if (mergeCellsSetting) {
	    var colCount = this.countCols();
	    var mergeParent;
	    for (var c = 0; c < colCount; c++) {
	      mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.startRow, c);
	      if (mergeParent) {
	        if (mergeParent.row < calc.startRow) {
	          calc.startRow = mergeParent.row;
	          return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards
	        }
	      }
	      mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.endRow, c);
	      if (mergeParent) {
	        var mergeEnd = mergeParent.row + mergeParent.rowspan - 1;
	        if (mergeEnd > calc.endRow) {
	          calc.endRow = mergeEnd;
	          return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards
	        }
	      }
	    }
	  }
	};
	
	var afterViewportColumnCalculatorOverride = function afterViewportColumnCalculatorOverride(calc) {
	  var mergeCellsSetting = this.getSettings().mergeCells;
	  if (mergeCellsSetting) {
	    var rowCount = this.countRows();
	    var mergeParent;
	    for (var r = 0; r < rowCount; r++) {
	      mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.startColumn);
	
	      if (mergeParent) {
	        if (mergeParent.col < calc.startColumn) {
	          calc.startColumn = mergeParent.col;
	          return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards
	        }
	      }
	      mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.endColumn);
	      if (mergeParent) {
	        var mergeEnd = mergeParent.col + mergeParent.colspan - 1;
	        if (mergeEnd > calc.endColumn) {
	          calc.endColumn = mergeEnd;
	          return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards
	        }
	      }
	    }
	  }
	};
	
	var isMultipleSelection = function isMultipleSelection(isMultiple) {
	  if (isMultiple && this.mergeCells) {
	    var mergedCells = this.mergeCells.mergedCellInfoCollection,
	        selectionRange = this.getSelectedRange();
	
	    for (var group in mergedCells) {
	      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;
	};
	
	function modifyAutofillRange(select, drag) {
	  var mergeCellsSetting = this.getSettings().mergeCells;
	
	  if (!mergeCellsSetting || this.selection.isMultiple()) {
	    return;
	  }
	  var info = this.mergeCells.mergedCellInfoCollection.getInfo(select[0], select[1]);
	
	  if (info) {
	    select[0] = info.row;
	    select[1] = info.col;
	    select[2] = info.row + info.rowspan - 1;
	    select[3] = info.col + info.colspan - 1;
	  }
	}
	
	function onAfterCreateCol(col, count) {
	  if (this.mergeCells) {
	    this.mergeCells.shiftCollection('right', col, count);
	  }
	}
	
	function onAfterRemoveCol(col, count) {
	  if (this.mergeCells) {
	    this.mergeCells.shiftCollection('left', col, count);
	  }
	}
	
	function onAfterCreateRow(row, count) {
	  if (this.mergeCells) {
	    this.mergeCells.shiftCollection('down', row, count);
	  }
	}
	
	function onAfterRemoveRow(row, count) {
	  if (this.mergeCells) {
	    this.mergeCells.shiftCollection('up', row, count);
	  }
	}
	
	var hook = _pluginHooks2.default.getSingleton();
	
	hook.add('beforeInit', beforeInit);
	hook.add('afterInit', afterInit);
	hook.add('afterUpdateSettings', afterUpdateSettings);
	hook.add('beforeKeyDown', onBeforeKeyDown);
	hook.add('modifyTransformStart', modifyTransformFactory('modifyTransformStart'));
	hook.add('modifyTransformEnd', modifyTransformFactory('modifyTransformEnd'));
	hook.add('beforeSetRangeEnd', beforeSetRangeEnd);
	hook.add('beforeDrawBorders', beforeDrawAreaBorders);
	hook.add('afterIsMultipleSelection', isMultipleSelection);
	hook.add('afterRenderer', afterRenderer);
	hook.add('afterContextMenuDefaultOptions', addMergeActionsToContextMenu);
	hook.add('afterGetCellMeta', afterGetCellMeta);
	hook.add('afterViewportRowCalculatorOverride', afterViewportRowCalculatorOverride);
	hook.add('afterViewportColumnCalculatorOverride', afterViewportColumnCalculatorOverride);
	hook.add('modifyAutofillRange', modifyAutofillRange);
	hook.add('afterCreateCol', onAfterCreateCol);
	hook.add('afterRemoveCol', onAfterRemoveCol);
	hook.add('afterCreateRow', onAfterCreateRow);
	hook.add('afterRemoveRow', onAfterRemoveRow);
	
	exports.default = MergeCells;
	
	/***/ }),
	/* 302 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _element = __webpack_require__(0);
	
	var _browser = __webpack_require__(26);
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _eventManager = __webpack_require__(4);
	
	var _eventManager2 = _interopRequireDefault(_eventManager);
	
	var _plugins = __webpack_require__(5);
	
	var _src = __webpack_require__(12);
	
	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; }
	
	/**
	 * @private
	 * @plugin MultipleSelectionHandles
	 */
	var MultipleSelectionHandles = function (_BasePlugin) {
	  _inherits(MultipleSelectionHandles, _BasePlugin);
	
	  /**
	   * @param {Object} hotInstance
	   */
	  function MultipleSelectionHandles(hotInstance) {
	    _classCallCheck(this, MultipleSelectionHandles);
	
	    /**
	     * @type {Array}
	     */
	    var _this2 = _possibleConstructorReturn(this, (MultipleSelectionHandles.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles)).call(this, hotInstance));
	
	    _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}
	   */
	
	
	  _createClass(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 _eventManager2.default(this);
	      }
	      this.registerListeners();
	      _get(MultipleSelectionHandles.prototype.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Bind the touch events
	     * @private
	     */
	
	  }, {
	    key: 'registerListeners',
	    value: function registerListeners() {
	      var _this = this;
	
	      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(this.hot.rootElement, 'touchstart', function (event) {
	        var selectedRange = void 0;
	
	        if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) {
	          selectedRange = _this.hot.getSelectedRange();
	
	          _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.getSelectedRange();
	
	          _this.dragged.push('bottomRight');
	
	          _this.touchStartRange = {
	            width: selectedRange.getWidth(),
	            height: selectedRange.getHeight(),
	            direction: selectedRange.getDirection()
	          };
	
	          event.preventDefault();
	          return false;
	        }
	      });
	
	      this.eventManager.addEventListener(this.hot.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(this.hot.rootElement, 'touchmove', function (event) {
	        var scrollTop = (0, _element.getWindowScrollTop)(),
	            scrollLeft = (0, _element.getWindowScrollLeft)(),
	            endTarget = void 0,
	            targetCoords = void 0,
	            selectedRange = void 0,
	            rangeWidth = void 0,
	            rangeHeight = void 0,
	            rangeDirection = void 0,
	            newRangeCoords = void 0;
	
	        if (_this.dragged.length === 0) {
	          return;
	        }
	
	        endTarget = document.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.getSelectedRange();
	          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(),
	          bottomRightCorner = selectedRange.getBottomRightCorner(),
	          bottomLeftCorner = selectedRange.getBottomLeftCorner(),
	          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;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('multipleSelectionHandles', MultipleSelectionHandles);
	
	exports.default = MultipleSelectionHandles;
	
	/***/ }),
	/* 303 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _jsonPatchDuplex = __webpack_require__(179);
	
	var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex);
	
	var _dataObserver = __webpack_require__(304);
	
	var _dataObserver2 = _interopRequireDefault(_dataObserver);
	
	var _array = __webpack_require__(2);
	
	var _plugins = __webpack_require__(5);
	
	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; }
	
	// 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 = function (_BasePlugin) {
	  _inherits(ObserveChanges, _BasePlugin);
	
	  function ObserveChanges(hotInstance) {
	    _classCallCheck(this, ObserveChanges);
	
	    /**
	     * Instance of {@link DataObserver}.
	     *
	     * @type {DataObserver}
	     */
	    var _this = _possibleConstructorReturn(this, (ObserveChanges.__proto__ || Object.getPrototypeOf(ObserveChanges)).call(this, hotInstance));
	
	    _this.observer = null;
	    return _this;
	  }
	
	  /**
	   * Check if the plugin is enabled in the handsontable settings.
	   *
	   * @returns {Boolean}
	   */
	
	
	  _createClass(ObserveChanges, [{
	    key: 'isEnabled',
	    value: function isEnabled() {
	      return this.hot.getSettings().observeChanges;
	    }
	
	    /**
	     * Enable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'enablePlugin',
	    value: function enablePlugin() {
	      var _this2 = this;
	
	      if (this.enabled) {
	        return;
	      }
	      if (!this.observer) {
	        this.observer = new _dataObserver2.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);
	      });
	
	      _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'enablePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      if (this.observer) {
	        this.observer.destroy();
	        this.observer = null;
	        this._deletePublicApi();
	      }
	
	      _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(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 = 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());
	      }
	    }
	
	    /**
	     * Destroy plugin instance.
	     */
	
	  }, {
	    key: 'destroy',
	    value: function destroy() {
	      if (this.observer) {
	        this.observer.destroy();
	        this._deletePublicApi();
	      }
	      _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(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();
	      };
	    }
	
	    /**
	     * Delete 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;
	}(_base2.default);
	
	exports.default = ObserveChanges;
	
	
	(0, _plugins.registerPlugin)('observeChanges', ObserveChanges);
	
	/***/ }),
	/* 304 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _jsonPatchDuplex = __webpack_require__(179);
	
	var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex);
	
	var _localHooks = __webpack_require__(87);
	
	var _localHooks2 = _interopRequireDefault(_localHooks);
	
	var _object = __webpack_require__(1);
	
	var _utils = __webpack_require__(305);
	
	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"); } }
	
	/**
	 * @class DataObserver
	 * @plugin ObserveChanges
	 */
	var DataObserver = function () {
	  function DataObserver(observedData) {
	    _classCallCheck(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
	   */
	
	
	  _createClass(DataObserver, [{
	    key: 'setObservedData',
	    value: function setObservedData(observedData) {
	      var _this = this;
	
	      if (this.observer) {
	        _jsonPatchDuplex2.default.unobserve(this.observedData, this.observer);
	      }
	      this.observedData = observedData;
	      this.observer = _jsonPatchDuplex2.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() {
	      _jsonPatchDuplex2.default.unobserve(this.observedData, this.observer);
	      this.observedData = null;
	      this.observer = null;
	    }
	  }]);
	
	  return DataObserver;
	}();
	
	(0, _object.mixin)(DataObserver, _localHooks2.default);
	
	exports.default = DataObserver;
	
	/***/ }),
	/* 305 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _slicedToArray = function () { function sliceIterator(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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	exports.cleanPatches = cleanPatches;
	exports.parsePath = parsePath;
	
	var _array = __webpack_require__(2);
	
	/**
	 * 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.
	   */
	  patches = (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
	   */
	  patches = (0, _array.arrayMap)(patches, 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.
	   */
	  patches = (0, _array.arrayFilter)(patches, 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 patches;
	}
	
	/**
	 * 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 = _slicedToArray(match, 3),
	      row = _match[1],
	      column = _match[2];
	
	  return {
	    row: parseInt(row, 10),
	    col: /^\d*$/.test(column) ? parseInt(column, 10) : column
	  };
	}
	
	/***/ }),
	/* 306 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _plugins = __webpack_require__(5);
	
	var _object = __webpack_require__(1);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function Storage(prefix) {
	  var savedKeys;
	
	  var saveSavedKeys = function saveSavedKeys() {
	    window.localStorage[prefix + '__persistentStateKeys'] = JSON.stringify(savedKeys);
	  };
	
	  var loadSavedKeys = function loadSavedKeys() {
	    var keysJSON = window.localStorage[prefix + '__persistentStateKeys'];
	    var keys = typeof keysJSON == 'string' ? JSON.parse(keysJSON) : void 0;
	    savedKeys = keys ? keys : [];
	  };
	
	  var clearSavedKeys = function clearSavedKeys() {
	    savedKeys = [];
	    saveSavedKeys();
	  };
	
	  loadSavedKeys();
	
	  this.saveValue = function (key, value) {
	    window.localStorage[prefix + '_' + key] = JSON.stringify(value);
	    if (savedKeys.indexOf(key) == -1) {
	      savedKeys.push(key);
	      saveSavedKeys();
	    }
	  };
	
	  this.loadValue = function (key, defaultValue) {
	
	    key = typeof key === 'undefined' ? defaultValue : key;
	
	    var value = window.localStorage[prefix + '_' + key];
	
	    return typeof value == 'undefined' ? void 0 : JSON.parse(value);
	  };
	
	  this.reset = function (key) {
	    window.localStorage.removeItem(prefix + '_' + key);
	  };
	
	  this.resetAll = function () {
	    for (var index = 0; index < savedKeys.length; index++) {
	      window.localStorage.removeItem(prefix + '_' + savedKeys[index]);
	    }
	
	    clearSavedKeys();
	  };
	}
	
	/**
	 * @private
	 * @class PersistentState
	 * @plugin PersistentState
	 */
	function HandsontablePersistentState() {
	  var plugin = this;
	
	  this.init = function () {
	    var instance = this,
	        pluginSettings = instance.getSettings().persistentState;
	
	    plugin.enabled = !!pluginSettings;
	
	    if (!plugin.enabled) {
	      removeHooks.call(instance);
	      return;
	    }
	
	    if (!instance.storage) {
	      instance.storage = new Storage(instance.rootElement.id);
	    }
	
	    instance.resetState = plugin.resetValue;
	
	    addHooks.call(instance);
	  };
	
	  this.saveValue = function (key, value) {
	    var instance = this;
	
	    instance.storage.saveValue(key, value);
	  };
	
	  this.loadValue = function (key, saveTo) {
	    var instance = this;
	
	    saveTo.value = instance.storage.loadValue(key);
	  };
	
	  this.resetValue = function (key) {
	    var instance = this;
	
	    if (typeof key === 'undefined') {
	      instance.storage.resetAll();
	    } else {
	      instance.storage.reset(key);
	    }
	  };
	
	  var hooks = {
	    persistentStateSave: plugin.saveValue,
	    persistentStateLoad: plugin.loadValue,
	    persistentStateReset: plugin.resetValue
	  };
	
	  for (var hookName in hooks) {
	    if ((0, _object.hasOwnProperty)(hooks, hookName)) {
	      _pluginHooks2.default.getSingleton().register(hookName);
	    }
	  }
	
	  function addHooks() {
	    var instance = this;
	
	    for (var hookName in hooks) {
	      if ((0, _object.hasOwnProperty)(hooks, hookName)) {
	        instance.addHook(hookName, hooks[hookName]);
	      }
	    }
	  }
	
	  function removeHooks() {
	    var instance = this;
	
	    for (var hookName in hooks) {
	      if ((0, _object.hasOwnProperty)(hooks, hookName)) {
	        instance.removeHook(hookName, hooks[hookName]);
	      }
	    }
	  }
	}
	
	var htPersistentState = new HandsontablePersistentState();
	
	_pluginHooks2.default.getSingleton().add('beforeInit', htPersistentState.init);
	_pluginHooks2.default.getSingleton().add('afterUpdateSettings', htPersistentState.init);
	
	exports.default = HandsontablePersistentState;
	
	/***/ }),
	/* 307 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _element = __webpack_require__(0);
	
	var _renderers = __webpack_require__(8);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * @private
	 * @plugin Search
	 */
	function Search(instance) {
	  this.query = function (queryStr, callback, queryMethod) {
	    var rowCount = instance.countRows();
	    var colCount = instance.countCols();
	    var queryResult = [];
	
	    if (!callback) {
	      callback = Search.global.getDefaultCallback();
	    }
	
	    if (!queryMethod) {
	      queryMethod = Search.global.getDefaultQueryMethod();
	    }
	
	    for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) {
	      for (var colIndex = 0; colIndex < colCount; colIndex++) {
	        var cellData = instance.getDataAtCell(rowIndex, colIndex);
	        var cellProperties = instance.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;
	  };
	};
	
	Search.DEFAULT_CALLBACK = function (instance, row, col, data, testResult) {
	  instance.getCellMeta(row, col).isSearchResult = testResult;
	};
	
	Search.DEFAULT_QUERY_METHOD = function (query, value) {
	  if (typeof query == 'undefined' || query == null || !query.toLowerCase || query.length === 0) {
	    return false;
	  }
	  if (typeof value == 'undefined' || value == null) {
	    return false;
	  }
	
	  return value.toString().toLowerCase().indexOf(query.toLowerCase()) != -1;
	};
	
	Search.DEFAULT_SEARCH_RESULT_CLASS = 'htSearchResult';
	
	Search.global = function () {
	
	  var defaultCallback = Search.DEFAULT_CALLBACK;
	  var defaultQueryMethod = Search.DEFAULT_QUERY_METHOD;
	  var defaultSearchResultClass = Search.DEFAULT_SEARCH_RESULT_CLASS;
	
	  return {
	    getDefaultCallback: function getDefaultCallback() {
	      return defaultCallback;
	    },
	    setDefaultCallback: function setDefaultCallback(newDefaultCallback) {
	      defaultCallback = newDefaultCallback;
	    },
	    getDefaultQueryMethod: function getDefaultQueryMethod() {
	      return defaultQueryMethod;
	    },
	    setDefaultQueryMethod: function setDefaultQueryMethod(newDefaultQueryMethod) {
	      defaultQueryMethod = newDefaultQueryMethod;
	    },
	    getDefaultSearchResultClass: function getDefaultSearchResultClass() {
	      return defaultSearchResultClass;
	    },
	    setDefaultSearchResultClass: function setDefaultSearchResultClass(newSearchResultClass) {
	      defaultSearchResultClass = newSearchResultClass;
	    }
	  };
	}();
	
	function SearchCellDecorator(instance, TD, row, col, prop, value, cellProperties) {
	  var searchResultClass = cellProperties.search !== null && _typeof(cellProperties.search) == 'object' && cellProperties.search.searchResultClass || Search.global.getDefaultSearchResultClass();
	
	  if (cellProperties.isSearchResult) {
	    (0, _element.addClass)(TD, searchResultClass);
	  } else {
	    (0, _element.removeClass)(TD, searchResultClass);
	  }
	};
	
	var originalBaseRenderer = (0, _renderers.getRenderer)('base');
	
	(0, _renderers.registerRenderer)('base', function (instance, TD, row, col, prop, value, cellProperties) {
	  originalBaseRenderer.apply(this, arguments);
	  SearchCellDecorator.apply(this, arguments);
	});
	
	function init() {
	  var instance = this;
	
	  var pluginEnabled = !!instance.getSettings().search;
	
	  if (pluginEnabled) {
	    instance.search = new Search(instance);
	  } else {
	    delete instance.search;
	  }
	}
	
	_pluginHooks2.default.getSingleton().add('afterInit', init);
	_pluginHooks2.default.getSingleton().add('afterUpdateSettings', init);
	
	exports.default = Search;
	
	/***/ }),
	/* 308 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	exports.__esModule = true;
	
	var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
	
	var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
	
	var _element = __webpack_require__(0);
	
	var _array = __webpack_require__(2);
	
	var _base = __webpack_require__(13);
	
	var _base2 = _interopRequireDefault(_base);
	
	var _plugins = __webpack_require__(5);
	
	var _feature = __webpack_require__(34);
	
	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; }
	
	/**
	 * @private
	 * @plugin TouchScroll
	 * @class TouchScroll
	 */
	var TouchScroll = function (_BasePlugin) {
	  _inherits(TouchScroll, _BasePlugin);
	
	  function TouchScroll(hotInstance) {
	    _classCallCheck(this, TouchScroll);
	
	    /**
	     * Collection of scrollbars to update.
	     *
	     * @type {Array}
	     */
	    var _this = _possibleConstructorReturn(this, (TouchScroll.__proto__ || Object.getPrototypeOf(TouchScroll)).call(this, hotInstance));
	
	    _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}
	   */
	
	
	  _createClass(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();
	
	      _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(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;
	
	      _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'updatePlugin', this).call(this);
	    }
	
	    /**
	     * Disable plugin for this Handsontable instance.
	     */
	
	  }, {
	    key: 'disablePlugin',
	    value: function disablePlugin() {
	      _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(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 _hot$view$wt$wtOverla = this.hot.view.wt.wtOverlays,
	          topOverlay = _hot$view$wt$wtOverla.topOverlay,
	          bottomOverlay = _hot$view$wt$wtOverla.bottomOverlay,
	          leftOverlay = _hot$view$wt$wtOverla.leftOverlay,
	          topLeftCornerOverlay = _hot$view$wt$wtOverla.topLeftCornerOverlay,
	          bottomLeftCornerOverlay = _hot$view$wt$wtOverla.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;
	}(_base2.default);
	
	(0, _plugins.registerPlugin)('touchScroll', TouchScroll);
	
	exports.default = TouchScroll;
	
	/***/ }),
	/* 309 */
	/***/ (function(module, exports, __webpack_require__) {
	
	"use strict";
	
	
	var _pluginHooks = __webpack_require__(7);
	
	var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
	
	var _array = __webpack_require__(2);
	
	var _number = __webpack_require__(6);
	
	var _object = __webpack_require__(1);
	
	var _event = __webpack_require__(10);
	
	var _src = __webpack_require__(12);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/**
	 * @description
	 * Handsontable UndoRedo plugin. It allows to undo and redo certain actions done in the table.
	 * Please note, that not all actions are currently undo-able.
	 *
	 * @example
	 * ```js
	 * ...
	 * undo: true
	 * ...
	 * ```
	 * @class UndoRedo
	 * @plugin UndoRedo
	 */
	/**
	 * Handsontable UndoRedo class
	 */
	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') {
	      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();
	
	    index = (originalData.length + index) % originalData.length;
	
	    var removedData = (0, _object.deepClone)(originalData.slice(index, index + amount));
	
	    plugin.done(new UndoRedo.RemoveRowAction(index, 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();
	
	    index = (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)(index, index + (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', index + i));
	    });
	
	    if (Array.isArray(instance.getSettings().colHeaders)) {
	      (0, _number.rangeEach)(amount - 1, function (i) {
	        headers.push(instance.getSettings().colHeaders[instance.runHooks('modifyCol', index + i)] || null);
	      });
	    }
	
	    var manualColumnMovePlugin = plugin.instance.getPlugin('manualColumnMove');
	
	    var columnsMap = manualColumnMovePlugin.isEnabled() ? manualColumnMovePlugin.columnsMapper.__arrayMap : [];
	    var action = new UndoRedo.RemoveColumnAction(index, 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));
	  });
	};
	
	UndoRedo.prototype.done = function (action) {
	  if (!this.ignoreNewActions) {
	    this.doneActions.push(action);
	    this.undoneActions.length = 0;
	  }
	};
	
	/**
	 * Undo last edit.
	 *
	 * @function undo
	 * @memberof UndoRedo#
	 */
	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 edit (used to reverse an undo).
	 *
	 * @function redo
	 * @memberof UndoRedo#
	 */
	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);
	  }
	};
	
	/**
	 * Check 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;
	};
	
	/**
	 * Check 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.
	 */
	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),
	      emptyRowsAtTheEnd = instance.countEmptyRows(true),
	      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.
	 */
	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(),
	      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.
	 */
	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.
	 */
	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.
	 */
	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 = void 0;
	  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[this.indexes.length - 1], '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[this.indexes.length - 1], '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.
	 */
	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) {
	  if (!instance.getPlugin('contextMenu').isEnabled()) {
	    return;
	  }
	  for (var row = this.range.from.row; row <= this.range.to.row; row++) {
	    for (var col = this.range.from.col; col <= this.range.to.col; col++) {
	      instance.setCellMeta(row, col, 'className', this.stateBefore[row][col] || ' htLeft');
	    }
	  }
	
	  instance.addHookOnce('afterRender', undoneCallback);
	  instance.render();
	};
	UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback) {
	  if (!instance.getPlugin('contextMenu').isEnabled()) {
	    return;
	  }
	  instance.selectCell(this.range.from.row, this.range.from.col, this.range.to.row, this.range.to.col);
	  instance.getPlugin('contextMenu').executeCommand('alignment:' + this.alignment.replace('ht', '').toLowerCase());
	
	  instance.addHookOnce('afterRender', undoneCallback);
	  instance.render();
	};
	
	/**
	 * Filters action.
	 */
	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();
	};
	
	/**
	 * ManualRowMove action.
	 * @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++) {
	    newRows.push(this.target + i);
	  }
	  manualRowMove.moveRows(newRows.slice(), newTarget);
	  instance.render();
	
	  instance.selection.setRangeStartOnly(new _src.CellCoords(this.rows[0], 0));
	  instance.selection.setRangeEnd(new _src.CellCoords(this.rows[this.rows.length - 1], instance.countCols() - 1));
	};
	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.selection.setRangeStartOnly(new _src.CellCoords(startSelection, 0));
	  instance.selection.setRangeEnd(new _src.CellCoords(startSelection + this.rows.length - 1, instance.countCols() - 1));
	};
	
	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 = _pluginHooks2.default.getSingleton();
	
	hook.add('afterInit', init);
	hook.add('afterUpdateSettings', init);
	
	hook.register('beforeUndo');
	hook.register('afterUndo');
	hook.register('beforeRedo');
	hook.register('afterRedo');
	
	/***/ })
	/******/ ])["default"];
	});
	//# sourceMappingURL=handsontable.js.map
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(22)))

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

	/* WEBPACK VAR INJECTION */(function(module) {//! moment.js
	//! version : 2.18.1
	//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
	//! license : MIT
	//! momentjs.com
	
	;(function (global, factory) {
	     true ? module.exports = factory() :
	    typeof define === 'function' && define.amd ? define(factory) :
	    global.moment = factory()
	}(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) {
	    var k;
	    for (k in obj) {
	        // even if its not own property I'd still call it non-empty
	        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;
	    };
	}
	
	var some$1 = some;
	
	function isValid(m) {
	    if (m._isValid == null) {
	        var flags = getParsingFlags(m);
	        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {
	            return i != null;
	        });
	        var isNowValid = !isNaN(m._d.getTime()) &&
	            flags.overflow < 0 &&
	            !flags.empty &&
	            !flags.invalidMonth &&
	            !flags.invalidWeekday &&
	            !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 keys$1 = keys;
	
	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 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()) {
	        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 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]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){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;
	
	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;
	    };
	}
	
	var indexOf$1 = indexOf;
	
	function daysInMonth(year, month) {
	    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
	}
	
	// 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$1.call(this._shortMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    } else {
	        if (format === 'MMM') {
	            ii = indexOf$1.call(this._shortMonthsParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.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');
	}
	
	// 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 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$1.call(this._weekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else if (format === 'ddd') {
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    } else {
	        if (format === 'dddd') {
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else if (format === 'ddd') {
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.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;
	            __webpack_require__(235)("./" + name);
	            // because defineLocale currently also sets the global locale, we
	            // want to undo that for lazy loaded locales
	            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, parentConfig = baseConfig;
	        // MERGE
	        if (locales[name] != null) {
	            parentConfig = locales[name]._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$1(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;
	}
	
	// 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 basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;
	
	// date and time from ref 2822 format
	function configFromRFC2822(config) {
	    var string, match, dayFormat,
	        dateFormat, timeFormat, tzFormat;
	    var timezones = {
	        ' GMT': ' +0000',
	        ' EDT': ' -0400',
	        ' EST': ' -0500',
	        ' CDT': ' -0500',
	        ' CST': ' -0600',
	        ' MDT': ' -0600',
	        ' MST': ' -0700',
	        ' PDT': ' -0700',
	        ' PST': ' -0800'
	    };
	    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';
	    var timezone, timezoneIndex;
	
	    string = config._i
	        .replace(/\([^\)]*\)|[\n\t]/g, ' ') // Remove comments and folding whitespace
	        .replace(/(\s\s+)/g, ' ') // Replace multiple-spaces with a single space
	        .replace(/^\s|\s$/g, ''); // Remove leading and trailing spaces
	    match = basicRfcRegex.exec(string);
	
	    if (match) {
	        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';
	        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');
	        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');
	
	        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
	        if (match[1]) { // day of week given
	            var momentDate = new Date(match[2]);
	            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];
	
	            if (match[1].substr(0,3) !== momentDay) {
	                getParsingFlags(config).weekdayMismatch = true;
	                config._isValid = false;
	                return;
	            }
	        }
	
	        switch (match[5].length) {
	            case 2: // military
	                if (timezoneIndex === 0) {
	                    timezone = ' +0000';
	                } else {
	                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;
	                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +
	                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';
	                }
	                break;
	            case 4: // Zone
	                timezone = timezones[match[5]];
	                break;
	            default: // UT or +/-9999
	                timezone = timezones[' GMT'];
	        }
	        match[5] = timezone;
	        config._i = match.splice(1).join('');
	        tzFormat = ' ZZ';
	        config._f = dayFormat + dateFormat + timeFormat + tzFormat;
	        configFromStringAndFormat(config);
	        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' : ''));
	    }
	);
	
	// 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, 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);
	    // 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;
	    }
	}
	
	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;
	    }
	}
	
	// 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 (!(ordering.indexOf(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 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 = {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 (milliseconds) {
	        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
	    }
	    if (days) {
	        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
	    }
	    if (months) {
	        setMonth(mom, get(mom, 'Month') + months * 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);
	
	    if (units === 'year' || units === 'month' || units === 'quarter') {
	        output = monthDiff(this, that);
	        if (units === 'quarter') {
	            output = output / 3;
	        } else if (units === 'year') {
	            output = output / 12;
	        }
	    } else {
	        delta = this - that;
	        output = units === 'second' ? delta / 1e3 : // 1000
	            units === 'minute' ? delta / 6e4 : // 1000 * 60
	            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
	            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
	            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
	            delta;
	    }
	    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() {
	    if (!this.isValid()) {
	        return null;
	    }
	    var m = this.clone().utc();
	    if (m.year() < 0 || m.year() > 9999) {
	        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	    }
	    if (isFunction(Date.prototype.toISOString)) {
	        // native implementation is ~50x faster, use it when we can
	        return this.toDate().toISOString();
	    }
	    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	}
	
	/**
	 * 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], 10);
	});
	
	// 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 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 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;
	    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';
	    }
	
	    return (total < 0 ? '-' : '') +
	        'P' +
	        (Y ? Y + 'Y' : '') +
	        (M ? M + 'M' : '') +
	        (D ? D + 'D' : '') +
	        ((h || m || s) ? 'T' : '') +
	        (h ? h + 'H' : '') +
	        (m ? m + 'M' : '') +
	        (s ? 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.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.18.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;
	
	return hooks;
	
	})));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(145)(module)))

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

	var map = {
		"./af": 236,
		"./af.js": 236,
		"./ar": 237,
		"./ar-dz": 238,
		"./ar-dz.js": 238,
		"./ar-kw": 239,
		"./ar-kw.js": 239,
		"./ar-ly": 240,
		"./ar-ly.js": 240,
		"./ar-ma": 241,
		"./ar-ma.js": 241,
		"./ar-sa": 242,
		"./ar-sa.js": 242,
		"./ar-tn": 243,
		"./ar-tn.js": 243,
		"./ar.js": 237,
		"./az": 244,
		"./az.js": 244,
		"./be": 245,
		"./be.js": 245,
		"./bg": 246,
		"./bg.js": 246,
		"./bn": 247,
		"./bn.js": 247,
		"./bo": 248,
		"./bo.js": 248,
		"./br": 249,
		"./br.js": 249,
		"./bs": 250,
		"./bs.js": 250,
		"./ca": 251,
		"./ca.js": 251,
		"./cs": 252,
		"./cs.js": 252,
		"./cv": 253,
		"./cv.js": 253,
		"./cy": 254,
		"./cy.js": 254,
		"./da": 255,
		"./da.js": 255,
		"./de": 256,
		"./de-at": 257,
		"./de-at.js": 257,
		"./de-ch": 258,
		"./de-ch.js": 258,
		"./de.js": 256,
		"./dv": 259,
		"./dv.js": 259,
		"./el": 260,
		"./el.js": 260,
		"./en-au": 261,
		"./en-au.js": 261,
		"./en-ca": 262,
		"./en-ca.js": 262,
		"./en-gb": 263,
		"./en-gb.js": 263,
		"./en-ie": 264,
		"./en-ie.js": 264,
		"./en-nz": 265,
		"./en-nz.js": 265,
		"./eo": 266,
		"./eo.js": 266,
		"./es": 267,
		"./es-do": 268,
		"./es-do.js": 268,
		"./es.js": 267,
		"./et": 269,
		"./et.js": 269,
		"./eu": 270,
		"./eu.js": 270,
		"./fa": 271,
		"./fa.js": 271,
		"./fi": 272,
		"./fi.js": 272,
		"./fo": 273,
		"./fo.js": 273,
		"./fr": 274,
		"./fr-ca": 275,
		"./fr-ca.js": 275,
		"./fr-ch": 276,
		"./fr-ch.js": 276,
		"./fr.js": 274,
		"./fy": 277,
		"./fy.js": 277,
		"./gd": 278,
		"./gd.js": 278,
		"./gl": 279,
		"./gl.js": 279,
		"./gom-latn": 280,
		"./gom-latn.js": 280,
		"./he": 281,
		"./he.js": 281,
		"./hi": 282,
		"./hi.js": 282,
		"./hr": 283,
		"./hr.js": 283,
		"./hu": 284,
		"./hu.js": 284,
		"./hy-am": 285,
		"./hy-am.js": 285,
		"./id": 286,
		"./id.js": 286,
		"./is": 287,
		"./is.js": 287,
		"./it": 288,
		"./it.js": 288,
		"./ja": 289,
		"./ja.js": 289,
		"./jv": 290,
		"./jv.js": 290,
		"./ka": 291,
		"./ka.js": 291,
		"./kk": 292,
		"./kk.js": 292,
		"./km": 293,
		"./km.js": 293,
		"./kn": 294,
		"./kn.js": 294,
		"./ko": 295,
		"./ko.js": 295,
		"./ky": 296,
		"./ky.js": 296,
		"./lb": 297,
		"./lb.js": 297,
		"./lo": 298,
		"./lo.js": 298,
		"./lt": 299,
		"./lt.js": 299,
		"./lv": 300,
		"./lv.js": 300,
		"./me": 301,
		"./me.js": 301,
		"./mi": 302,
		"./mi.js": 302,
		"./mk": 303,
		"./mk.js": 303,
		"./ml": 304,
		"./ml.js": 304,
		"./mr": 305,
		"./mr.js": 305,
		"./ms": 306,
		"./ms-my": 307,
		"./ms-my.js": 307,
		"./ms.js": 306,
		"./my": 308,
		"./my.js": 308,
		"./nb": 309,
		"./nb.js": 309,
		"./ne": 310,
		"./ne.js": 310,
		"./nl": 311,
		"./nl-be": 312,
		"./nl-be.js": 312,
		"./nl.js": 311,
		"./nn": 313,
		"./nn.js": 313,
		"./pa-in": 314,
		"./pa-in.js": 314,
		"./pl": 315,
		"./pl.js": 315,
		"./pt": 316,
		"./pt-br": 317,
		"./pt-br.js": 317,
		"./pt.js": 316,
		"./ro": 318,
		"./ro.js": 318,
		"./ru": 319,
		"./ru.js": 319,
		"./sd": 320,
		"./sd.js": 320,
		"./se": 321,
		"./se.js": 321,
		"./si": 322,
		"./si.js": 322,
		"./sk": 323,
		"./sk.js": 323,
		"./sl": 324,
		"./sl.js": 324,
		"./sq": 325,
		"./sq.js": 325,
		"./sr": 326,
		"./sr-cyrl": 327,
		"./sr-cyrl.js": 327,
		"./sr.js": 326,
		"./ss": 328,
		"./ss.js": 328,
		"./sv": 329,
		"./sv.js": 329,
		"./sw": 330,
		"./sw.js": 330,
		"./ta": 331,
		"./ta.js": 331,
		"./te": 332,
		"./te.js": 332,
		"./tet": 333,
		"./tet.js": 333,
		"./th": 334,
		"./th.js": 334,
		"./tl-ph": 335,
		"./tl-ph.js": 335,
		"./tlh": 336,
		"./tlh.js": 336,
		"./tr": 337,
		"./tr.js": 337,
		"./tzl": 338,
		"./tzl.js": 338,
		"./tzm": 339,
		"./tzm-latn": 340,
		"./tzm-latn.js": 340,
		"./tzm.js": 339,
		"./uk": 341,
		"./uk.js": 341,
		"./ur": 342,
		"./ur.js": 342,
		"./uz": 343,
		"./uz-latn": 344,
		"./uz-latn.js": 344,
		"./uz.js": 343,
		"./vi": 345,
		"./vi.js": 345,
		"./x-pseudo": 346,
		"./x-pseudo.js": 346,
		"./yo": 347,
		"./yo.js": 347,
		"./zh-cn": 348,
		"./zh-cn.js": 348,
		"./zh-hk": 349,
		"./zh-hk.js": 349,
		"./zh-tw": 350,
		"./zh-tw.js": 350
	};
	function webpackContext(req) {
		return __webpack_require__(webpackContextResolve(req));
	};
	function webpackContextResolve(req) {
		return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
	};
	webpackContext.keys = function webpackContextKeys() {
		return Object.keys(map);
	};
	webpackContext.resolve = webpackContextResolve;
	module.exports = webpackContext;
	webpackContext.id = 235;


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

	//! moment.js locale configuration
	//! locale : Afrikaans [af]
	//! author : Werner Mollentze : https://github.com/wernerm
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var af = moment.defineLocale('af', {
	    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),
	    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
	    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
	    meridiemParse: /vm|nm/i,
	    isPM : function (input) {
	        return /^nm$/i.test(input);
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower ? 'vm' : 'VM';
	        } else {
	            return isLower ? 'nm' : 'NM';
	        }
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Vandag om] LT',
	        nextDay : '[Môre om] LT',
	        nextWeek : 'dddd [om] LT',
	        lastDay : '[Gister om] LT',
	        lastWeek : '[Laas] dddd [om] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'oor %s',
	        past : '%s gelede',
	        s : '\'n paar sekondes',
	        m : '\'n minuut',
	        mm : '%d minute',
	        h : '\'n uur',
	        hh : '%d ure',
	        d : '\'n dag',
	        dd : '%d dae',
	        M : '\'n maand',
	        MM : '%d maande',
	        y : '\'n jaar',
	        yy : '%d jaar'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter
	    },
	    week : {
	        dow : 1, // Maandag is die eerste dag van die week.
	        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
	    }
	});
	
	return af;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic [ar]
	//! author : Abdel Said: https://github.com/abdelsaid
	//! author : Ahmed Elkhatib
	//! author : forabi https://github.com/forabi
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '١',
	    '2': '٢',
	    '3': '٣',
	    '4': '٤',
	    '5': '٥',
	    '6': '٦',
	    '7': '٧',
	    '8': '٨',
	    '9': '٩',
	    '0': '٠'
	};
	var numberMap = {
	    '١': '1',
	    '٢': '2',
	    '٣': '3',
	    '٤': '4',
	    '٥': '5',
	    '٦': '6',
	    '٧': '7',
	    '٨': '8',
	    '٩': '9',
	    '٠': '0'
	};
	var pluralForm = function (n) {
	    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
	};
	var plurals = {
	    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
	    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
	    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
	    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
	    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
	    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
	};
	var pluralize = function (u) {
	    return function (number, withoutSuffix, string, isFuture) {
	        var f = pluralForm(number),
	            str = plurals[u][pluralForm(number)];
	        if (f === 2) {
	            str = str[withoutSuffix ? 0 : 1];
	        }
	        return str.replace(/%d/i, number);
	    };
	};
	var months = [
	    'كانون الثاني يناير',
	    'شباط فبراير',
	    'آذار مارس',
	    'نيسان أبريل',
	    'أيار مايو',
	    'حزيران يونيو',
	    'تموز يوليو',
	    'آب أغسطس',
	    'أيلول سبتمبر',
	    'تشرين الأول أكتوبر',
	    'تشرين الثاني نوفمبر',
	    'كانون الأول ديسمبر'
	];
	
	var ar = moment.defineLocale('ar', {
	    months : months,
	    monthsShort : months,
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/\u200FM/\u200FYYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم عند الساعة] LT',
	        nextDay: '[غدًا عند الساعة] LT',
	        nextWeek: 'dddd [عند الساعة] LT',
	        lastDay: '[أمس عند الساعة] LT',
	        lastWeek: 'dddd [عند الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'بعد %s',
	        past : 'منذ %s',
	        s : pluralize('s'),
	        m : pluralize('m'),
	        mm : pluralize('m'),
	        h : pluralize('h'),
	        hh : pluralize('h'),
	        d : pluralize('d'),
	        dd : pluralize('d'),
	        M : pluralize('M'),
	        MM : pluralize('M'),
	        y : pluralize('y'),
	        yy : pluralize('y')
	    },
	    preparse: function (string) {
	        return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ar;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Algeria) [ar-dz]
	//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arDz = moment.defineLocale('ar-dz', {
	    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 4  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arDz;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Kuwait) [ar-kw]
	//! author : Nusret Parlak: https://github.com/nusretparlak
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arKw = moment.defineLocale('ar-kw', {
	    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arKw;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Lybia) [ar-ly]
	//! author : Ali Hmer: https://github.com/kikoanis
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '1',
	    '2': '2',
	    '3': '3',
	    '4': '4',
	    '5': '5',
	    '6': '6',
	    '7': '7',
	    '8': '8',
	    '9': '9',
	    '0': '0'
	};
	var pluralForm = function (n) {
	    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
	};
	var plurals = {
	    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
	    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
	    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
	    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
	    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
	    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
	};
	var pluralize = function (u) {
	    return function (number, withoutSuffix, string, isFuture) {
	        var f = pluralForm(number),
	            str = plurals[u][pluralForm(number)];
	        if (f === 2) {
	            str = str[withoutSuffix ? 0 : 1];
	        }
	        return str.replace(/%d/i, number);
	    };
	};
	var months = [
	    'يناير',
	    'فبراير',
	    'مارس',
	    'أبريل',
	    'مايو',
	    'يونيو',
	    'يوليو',
	    'أغسطس',
	    'سبتمبر',
	    'أكتوبر',
	    'نوفمبر',
	    'ديسمبر'
	];
	
	var arLy = moment.defineLocale('ar-ly', {
	    months : months,
	    monthsShort : months,
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/\u200FM/\u200FYYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم عند الساعة] LT',
	        nextDay: '[غدًا عند الساعة] LT',
	        nextWeek: 'dddd [عند الساعة] LT',
	        lastDay: '[أمس عند الساعة] LT',
	        lastWeek: 'dddd [عند الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'بعد %s',
	        past : 'منذ %s',
	        s : pluralize('s'),
	        m : pluralize('m'),
	        mm : pluralize('m'),
	        h : pluralize('h'),
	        hh : pluralize('h'),
	        d : pluralize('d'),
	        dd : pluralize('d'),
	        M : pluralize('M'),
	        MM : pluralize('M'),
	        y : pluralize('y'),
	        yy : pluralize('y')
	    },
	    preparse: function (string) {
	        return string.replace(/\u200f/g, '').replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arLy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Morocco) [ar-ma]
	//! author : ElFadili Yassine : https://github.com/ElFadiliY
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arMa = moment.defineLocale('ar-ma', {
	    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arMa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Saudi Arabia) [ar-sa]
	//! author : Suhail Alkowaileet : https://github.com/xsoh
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '١',
	    '2': '٢',
	    '3': '٣',
	    '4': '٤',
	    '5': '٥',
	    '6': '٦',
	    '7': '٧',
	    '8': '٨',
	    '9': '٩',
	    '0': '٠'
	};
	var numberMap = {
	    '١': '1',
	    '٢': '2',
	    '٣': '3',
	    '٤': '4',
	    '٥': '5',
	    '٦': '6',
	    '٧': '7',
	    '٨': '8',
	    '٩': '9',
	    '٠': '0'
	};
	
	var arSa = moment.defineLocale('ar-sa', {
	    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    preparse: function (string) {
	        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        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.
	    }
	});
	
	return arSa;
	
	})));


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

	//! moment.js locale configuration
	//! locale  :  Arabic (Tunisia) [ar-tn]
	//! author : Nader Toukabri : https://github.com/naderio
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arTn = moment.defineLocale('ar-tn', {
	    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'في %s',
	        past: 'منذ %s',
	        s: 'ثوان',
	        m: 'دقيقة',
	        mm: '%d دقائق',
	        h: 'ساعة',
	        hh: '%d ساعات',
	        d: 'يوم',
	        dd: '%d أيام',
	        M: 'شهر',
	        MM: '%d أشهر',
	        y: 'سنة',
	        yy: '%d سنوات'
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return arTn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Azerbaijani [az]
	//! author : topchiyev : https://github.com/topchiyev
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    1: '-inci',
	    5: '-inci',
	    8: '-inci',
	    70: '-inci',
	    80: '-inci',
	    2: '-nci',
	    7: '-nci',
	    20: '-nci',
	    50: '-nci',
	    3: '-üncü',
	    4: '-üncü',
	    100: '-üncü',
	    6: '-ncı',
	    9: '-uncu',
	    10: '-uncu',
	    30: '-uncu',
	    60: '-ıncı',
	    90: '-ıncı'
	};
	
	var az = moment.defineLocale('az', {
	    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),
	    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
	    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),
	    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
	    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[bugün saat] LT',
	        nextDay : '[sabah saat] LT',
	        nextWeek : '[gələn həftə] dddd [saat] LT',
	        lastDay : '[dünən] LT',
	        lastWeek : '[keçən həftə] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s sonra',
	        past : '%s əvvəl',
	        s : 'birneçə saniyyə',
	        m : 'bir dəqiqə',
	        mm : '%d dəqiqə',
	        h : 'bir saat',
	        hh : '%d saat',
	        d : 'bir gün',
	        dd : '%d gün',
	        M : 'bir ay',
	        MM : '%d ay',
	        y : 'bir il',
	        yy : '%d il'
	    },
	    meridiemParse: /gecə|səhər|gündüz|axşam/,
	    isPM : function (input) {
	        return /^(gündüz|axşam)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'gecə';
	        } else if (hour < 12) {
	            return 'səhər';
	        } else if (hour < 17) {
	            return 'gündüz';
	        } else {
	            return 'axşam';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
	    ordinal : function (number) {
	        if (number === 0) {  // special case for zero
	            return number + '-ıncı';
	        }
	        var a = number % 10,
	            b = number % 100 - a,
	            c = number >= 100 ? 100 : null;
	        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return az;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Belarusian [be]
	//! author : Dmitry Demidov : https://github.com/demidov91
	//! author: Praleska: http://praleska.pro/
	//! Author : Menelion Elensúle : https://github.com/Oire
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
	        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
	        'dd': 'дзень_дні_дзён',
	        'MM': 'месяц_месяцы_месяцаў',
	        'yy': 'год_гады_гадоў'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'хвіліна' : 'хвіліну';
	    }
	    else if (key === 'h') {
	        return withoutSuffix ? 'гадзіна' : 'гадзіну';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	
	var be = moment.defineLocale('be', {
	    months : {
	        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),
	        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')
	    },
	    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),
	    weekdays : {
	        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),
	        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),
	        isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/
	    },
	    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
	    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY г.',
	        LLL : 'D MMMM YYYY г., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY г., HH:mm'
	    },
	    calendar : {
	        sameDay: '[Сёння ў] LT',
	        nextDay: '[Заўтра ў] LT',
	        lastDay: '[Учора ў] LT',
	        nextWeek: function () {
	            return '[У] dddd [ў] LT';
	        },
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 5:
	                case 6:
	                    return '[У мінулую] dddd [ў] LT';
	                case 1:
	                case 2:
	                case 4:
	                    return '[У мінулы] dddd [ў] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'праз %s',
	        past : '%s таму',
	        s : 'некалькі секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : relativeTimeWithPlural,
	        hh : relativeTimeWithPlural,
	        d : 'дзень',
	        dd : relativeTimeWithPlural,
	        M : 'месяц',
	        MM : relativeTimeWithPlural,
	        y : 'год',
	        yy : relativeTimeWithPlural
	    },
	    meridiemParse: /ночы|раніцы|дня|вечара/,
	    isPM : function (input) {
	        return /^(дня|вечара)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночы';
	        } else if (hour < 12) {
	            return 'раніцы';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечара';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	            case 'w':
	            case 'W':
	                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';
	            case 'D':
	                return number + '-га';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return be;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Bulgarian [bg]
	//! author : Krasen Borisov : https://github.com/kraz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var bg = moment.defineLocale('bg', {
	    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
	    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
	    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),
	    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
	    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'D.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay : '[Днес в] LT',
	        nextDay : '[Утре в] LT',
	        nextWeek : 'dddd [в] LT',
	        lastDay : '[Вчера в] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 6:
	                    return '[В изминалата] dddd [в] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[В изминалия] dddd [в] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'след %s',
	        past : 'преди %s',
	        s : 'няколко секунди',
	        m : 'минута',
	        mm : '%d минути',
	        h : 'час',
	        hh : '%d часа',
	        d : 'ден',
	        dd : '%d дни',
	        M : 'месец',
	        MM : '%d месеца',
	        y : 'година',
	        yy : '%d години'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
	    ordinal : function (number) {
	        var lastDigit = number % 10,
	            last2Digits = number % 100;
	        if (number === 0) {
	            return number + '-ев';
	        } else if (last2Digits === 0) {
	            return number + '-ен';
	        } else if (last2Digits > 10 && last2Digits < 20) {
	            return number + '-ти';
	        } else if (lastDigit === 1) {
	            return number + '-ви';
	        } else if (lastDigit === 2) {
	            return number + '-ри';
	        } else if (lastDigit === 7 || lastDigit === 8) {
	            return number + '-ми';
	        } else {
	            return number + '-ти';
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bg;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Bengali [bn]
	//! author : Kaushik Gandhi : https://github.com/kaushikgandhi
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '১',
	    '2': '২',
	    '3': '৩',
	    '4': '৪',
	    '5': '৫',
	    '6': '৬',
	    '7': '৭',
	    '8': '৮',
	    '9': '৯',
	    '0': '০'
	};
	var numberMap = {
	    '১': '1',
	    '২': '2',
	    '৩': '3',
	    '৪': '4',
	    '৫': '5',
	    '৬': '6',
	    '৭': '7',
	    '৮': '8',
	    '৯': '9',
	    '০': '0'
	};
	
	var bn = moment.defineLocale('bn', {
	    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),
	    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),
	    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),
	    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
	    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm সময়',
	        LTS : 'A h:mm:ss সময়',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm সময়',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
	    },
	    calendar : {
	        sameDay : '[আজ] LT',
	        nextDay : '[আগামীকাল] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[গতকাল] LT',
	        lastWeek : '[গত] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s পরে',
	        past : '%s আগে',
	        s : 'কয়েক সেকেন্ড',
	        m : 'এক মিনিট',
	        mm : '%d মিনিট',
	        h : 'এক ঘন্টা',
	        hh : '%d ঘন্টা',
	        d : 'এক দিন',
	        dd : '%d দিন',
	        M : 'এক মাস',
	        MM : '%d মাস',
	        y : 'এক বছর',
	        yy : '%d বছর'
	    },
	    preparse: function (string) {
	        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'রাত' && hour >= 4) ||
	                (meridiem === 'দুপুর' && hour < 5) ||
	                meridiem === 'বিকাল') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'রাত';
	        } else if (hour < 10) {
	            return 'সকাল';
	        } else if (hour < 17) {
	            return 'দুপুর';
	        } else if (hour < 20) {
	            return 'বিকাল';
	        } else {
	            return 'রাত';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return bn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tibetan [bo]
	//! author : Thupten N. Chakrishar : https://github.com/vajradog
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '༡',
	    '2': '༢',
	    '3': '༣',
	    '4': '༤',
	    '5': '༥',
	    '6': '༦',
	    '7': '༧',
	    '8': '༨',
	    '9': '༩',
	    '0': '༠'
	};
	var numberMap = {
	    '༡': '1',
	    '༢': '2',
	    '༣': '3',
	    '༤': '4',
	    '༥': '5',
	    '༦': '6',
	    '༧': '7',
	    '༨': '8',
	    '༩': '9',
	    '༠': '0'
	};
	
	var bo = moment.defineLocale('bo', {
	    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
	    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
	    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),
	    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
	    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[དི་རིང] LT',
	        nextDay : '[སང་ཉིན] LT',
	        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',
	        lastDay : '[ཁ་སང] LT',
	        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ལ་',
	        past : '%s སྔན་ལ',
	        s : 'ལམ་སང',
	        m : 'སྐར་མ་གཅིག',
	        mm : '%d སྐར་མ',
	        h : 'ཆུ་ཚོད་གཅིག',
	        hh : '%d ཆུ་ཚོད',
	        d : 'ཉིན་གཅིག',
	        dd : '%d ཉིན་',
	        M : 'ཟླ་བ་གཅིག',
	        MM : '%d ཟླ་བ',
	        y : 'ལོ་གཅིག',
	        yy : '%d ལོ'
	    },
	    preparse: function (string) {
	        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||
	                (meridiem === 'ཉིན་གུང' && hour < 5) ||
	                meridiem === 'དགོང་དག') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'མཚན་མོ';
	        } else if (hour < 10) {
	            return 'ཞོགས་ཀས';
	        } else if (hour < 17) {
	            return 'ཉིན་གུང';
	        } else if (hour < 20) {
	            return 'དགོང་དག';
	        } else {
	            return 'མཚན་མོ';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return bo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Breton [br]
	//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function relativeTimeWithMutation(number, withoutSuffix, key) {
	    var format = {
	        'mm': 'munutenn',
	        'MM': 'miz',
	        'dd': 'devezh'
	    };
	    return number + ' ' + mutation(format[key], number);
	}
	function specialMutationForYears(number) {
	    switch (lastNumber(number)) {
	        case 1:
	        case 3:
	        case 4:
	        case 5:
	        case 9:
	            return number + ' bloaz';
	        default:
	            return number + ' vloaz';
	    }
	}
	function lastNumber(number) {
	    if (number > 9) {
	        return lastNumber(number % 10);
	    }
	    return number;
	}
	function mutation(text, number) {
	    if (number === 2) {
	        return softMutation(text);
	    }
	    return text;
	}
	function softMutation(text) {
	    var mutationTable = {
	        'm': 'v',
	        'b': 'v',
	        'd': 'z'
	    };
	    if (mutationTable[text.charAt(0)] === undefined) {
	        return text;
	    }
	    return mutationTable[text.charAt(0)] + text.substring(1);
	}
	
	var br = moment.defineLocale('br', {
	    months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),
	    monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
	    weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'),
	    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
	    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h[e]mm A',
	        LTS : 'h[e]mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D [a viz] MMMM YYYY',
	        LLL : 'D [a viz] MMMM YYYY h[e]mm A',
	        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
	    },
	    calendar : {
	        sameDay : '[Hiziv da] LT',
	        nextDay : '[Warc\'hoazh da] LT',
	        nextWeek : 'dddd [da] LT',
	        lastDay : '[Dec\'h da] LT',
	        lastWeek : 'dddd [paset da] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'a-benn %s',
	        past : '%s \'zo',
	        s : 'un nebeud segondennoù',
	        m : 'ur vunutenn',
	        mm : relativeTimeWithMutation,
	        h : 'un eur',
	        hh : '%d eur',
	        d : 'un devezh',
	        dd : relativeTimeWithMutation,
	        M : 'ur miz',
	        MM : relativeTimeWithMutation,
	        y : 'ur bloaz',
	        yy : specialMutationForYears
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/,
	    ordinal : function (number) {
	        var output = (number === 1) ? 'añ' : 'vet';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return br;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Bosnian [bs]
	//! author : Nedim Cholich : https://github.com/frontyard
	//! based on (hr) translation by Bojan Marković
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
	        case 'mm':
	            if (number === 1) {
	                result += 'minuta';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'minute';
	            } else {
	                result += 'minuta';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'jedan sat' : 'jednog sata';
	        case 'hh':
	            if (number === 1) {
	                result += 'sat';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'sata';
	            } else {
	                result += 'sati';
	            }
	            return result;
	        case 'dd':
	            if (number === 1) {
	                result += 'dan';
	            } else {
	                result += 'dana';
	            }
	            return result;
	        case 'MM':
	            if (number === 1) {
	                result += 'mjesec';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'mjeseca';
	            } else {
	                result += 'mjeseci';
	            }
	            return result;
	        case 'yy':
	            if (number === 1) {
	                result += 'godina';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'godine';
	            } else {
	                result += 'godina';
	            }
	            return result;
	    }
	}
	
	var bs = moment.defineLocale('bs', {
	    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danas u] LT',
	        nextDay  : '[sutra u] LT',
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[jučer u] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                    return '[prošlu] dddd [u] LT';
	                case 6:
	                    return '[prošle] [subote] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prošli] dddd [u] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'par sekundi',
	        m      : translate,
	        mm     : translate,
	        h      : translate,
	        hh     : translate,
	        d      : 'dan',
	        dd     : translate,
	        M      : 'mjesec',
	        MM     : translate,
	        y      : 'godinu',
	        yy     : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bs;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Catalan [ca]
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ca = moment.defineLocale('ca', {
	    months : {
	        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
	        format: 'de gener_de febrer_de març_d\'abril_de maig_de juny_de juliol_d\'agost_de setembre_d\'octubre_de novembre_de desembre'.split('_'),
	        isFormat: /D[oD]?(\s)+MMMM/
	    },
	    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),
	    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
	    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : '[el] D MMMM [de] YYYY',
	        ll : 'D MMM YYYY',
	        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',
	        lll : 'D MMM YYYY, H:mm',
	        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',
	        llll : 'ddd D MMM YYYY, H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        nextDay : function () {
	            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        lastDay : function () {
	            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'd\'aquí %s',
	        past : 'fa %s',
	        s : 'uns segons',
	        m : 'un minut',
	        mm : '%d minuts',
	        h : 'una hora',
	        hh : '%d hores',
	        d : 'un dia',
	        dd : '%d dies',
	        M : 'un mes',
	        MM : '%d mesos',
	        y : 'un any',
	        yy : '%d anys'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/,
	    ordinal : function (number, period) {
	        var output = (number === 1) ? 'r' :
	            (number === 2) ? 'n' :
	            (number === 3) ? 'r' :
	            (number === 4) ? 't' : 'è';
	        if (period === 'w' || period === 'W') {
	            output = 'a';
	        }
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ca;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Czech [cs]
	//! author : petrbela : https://github.com/petrbela
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');
	var monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');
	function plural(n) {
	    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':  // a few seconds / in a few seconds / a few seconds ago
	            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
	        case 'm':  // a minute / in a minute / a minute ago
	            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
	        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'minuty' : 'minut');
	            } else {
	                return result + 'minutami';
	            }
	            break;
	        case 'h':  // an hour / in an hour / an hour ago
	            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
	        case 'hh': // 9 hours / in 9 hours / 9 hours ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'hodiny' : 'hodin');
	            } else {
	                return result + 'hodinami';
	            }
	            break;
	        case 'd':  // a day / in a day / a day ago
	            return (withoutSuffix || isFuture) ? 'den' : 'dnem';
	        case 'dd': // 9 days / in 9 days / 9 days ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'dny' : 'dní');
	            } else {
	                return result + 'dny';
	            }
	            break;
	        case 'M':  // a month / in a month / a month ago
	            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
	        case 'MM': // 9 months / in 9 months / 9 months ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'měsíce' : 'měsíců');
	            } else {
	                return result + 'měsíci';
	            }
	            break;
	        case 'y':  // a year / in a year / a year ago
	            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
	        case 'yy': // 9 years / in 9 years / 9 years ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'roky' : 'let');
	            } else {
	                return result + 'lety';
	            }
	            break;
	    }
	}
	
	var cs = moment.defineLocale('cs', {
	    months : months,
	    monthsShort : monthsShort,
	    monthsParse : (function (months, monthsShort) {
	        var i, _monthsParse = [];
	        for (i = 0; i < 12; i++) {
	            // use custom parser to solve problem with July (červenec)
	            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
	        }
	        return _monthsParse;
	    }(months, monthsShort)),
	    shortMonthsParse : (function (monthsShort) {
	        var i, _shortMonthsParse = [];
	        for (i = 0; i < 12; i++) {
	            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');
	        }
	        return _shortMonthsParse;
	    }(monthsShort)),
	    longMonthsParse : (function (months) {
	        var i, _longMonthsParse = [];
	        for (i = 0; i < 12; i++) {
	            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');
	        }
	        return _longMonthsParse;
	    }(months)),
	    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
	    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),
	    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
	    longDateFormat : {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd D. MMMM YYYY H:mm',
	        l : 'D. M. YYYY'
	    },
	    calendar : {
	        sameDay: '[dnes v] LT',
	        nextDay: '[zítra v] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v neděli v] LT';
	                case 1:
	                case 2:
	                    return '[v] dddd [v] LT';
	                case 3:
	                    return '[ve středu v] LT';
	                case 4:
	                    return '[ve čtvrtek v] LT';
	                case 5:
	                    return '[v pátek v] LT';
	                case 6:
	                    return '[v sobotu v] LT';
	            }
	        },
	        lastDay: '[včera v] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[minulou neděli v] LT';
	                case 1:
	                case 2:
	                    return '[minulé] dddd [v] LT';
	                case 3:
	                    return '[minulou středu v] LT';
	                case 4:
	                case 5:
	                    return '[minulý] dddd [v] LT';
	                case 6:
	                    return '[minulou sobotu v] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : 'před %s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return cs;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chuvash [cv]
	//! author : Anatoly Mironov : https://github.com/mirontoli
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var cv = moment.defineLocale('cv', {
	    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),
	    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
	    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),
	    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
	    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
	        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
	        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
	    },
	    calendar : {
	        sameDay: '[Паян] LT [сехетре]',
	        nextDay: '[Ыран] LT [сехетре]',
	        lastDay: '[Ӗнер] LT [сехетре]',
	        nextWeek: '[Ҫитес] dddd LT [сехетре]',
	        lastWeek: '[Иртнӗ] dddd LT [сехетре]',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : function (output) {
	            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';
	            return output + affix;
	        },
	        past : '%s каялла',
	        s : 'пӗр-ик ҫеккунт',
	        m : 'пӗр минут',
	        mm : '%d минут',
	        h : 'пӗр сехет',
	        hh : '%d сехет',
	        d : 'пӗр кун',
	        dd : '%d кун',
	        M : 'пӗр уйӑх',
	        MM : '%d уйӑх',
	        y : 'пӗр ҫул',
	        yy : '%d ҫул'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-мӗш/,
	    ordinal : '%d-мӗш',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return cv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Welsh [cy]
	//! author : Robert Allen : https://github.com/robgallen
	//! author : https://github.com/ryangreaves
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var cy = moment.defineLocale('cy', {
	    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),
	    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),
	    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),
	    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
	    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
	    weekdaysParseExact : true,
	    // time formats are the same as en-gb
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[Heddiw am] LT',
	        nextDay: '[Yfory am] LT',
	        nextWeek: 'dddd [am] LT',
	        lastDay: '[Ddoe am] LT',
	        lastWeek: 'dddd [diwethaf am] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'mewn %s',
	        past: '%s yn ôl',
	        s: 'ychydig eiliadau',
	        m: 'munud',
	        mm: '%d munud',
	        h: 'awr',
	        hh: '%d awr',
	        d: 'diwrnod',
	        dd: '%d diwrnod',
	        M: 'mis',
	        MM: '%d mis',
	        y: 'blwyddyn',
	        yy: '%d flynedd'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
	    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
	    ordinal: function (number) {
	        var b = number,
	            output = '',
	            lookup = [
	                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
	                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
	            ];
	        if (b > 20) {
	            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
	                output = 'fed'; // not 30ain, 70ain or 90ain
	            } else {
	                output = 'ain';
	            }
	        } else if (b > 0) {
	            output = lookup[b];
	        }
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return cy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Danish [da]
	//! author : Ulrik Nielsen : https://github.com/mrbase
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var da = moment.defineLocale('da', {
	    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
	    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),
	    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay : '[i dag kl.] LT',
	        nextDay : '[i morgen kl.] LT',
	        nextWeek : 'på dddd [kl.] LT',
	        lastDay : '[i går kl.] LT',
	        lastWeek : '[i] dddd[s kl.] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s siden',
	        s : 'få sekunder',
	        m : 'et minut',
	        mm : '%d minutter',
	        h : 'en time',
	        hh : '%d timer',
	        d : 'en dag',
	        dd : '%d dage',
	        M : 'en måned',
	        MM : '%d måneder',
	        y : 'et år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return da;
	
	})));


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

	//! moment.js locale configuration
	//! locale : German [de]
	//! author : lluchs : https://github.com/lluchs
	//! author: Menelion Elensúle: https://github.com/Oire
	//! author : Mikolaj Dadela : https://github.com/mik01aj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var de = moment.defineLocale('de', {
	    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd, D. MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return de;
	
	})));


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

	//! moment.js locale configuration
	//! locale : German (Austria) [de-at]
	//! author : lluchs : https://github.com/lluchs
	//! author: Menelion Elensúle: https://github.com/Oire
	//! author : Martin Groller : https://github.com/MadMG
	//! author : Mikolaj Dadela : https://github.com/mik01aj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var deAt = moment.defineLocale('de-at', {
	    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd, D. MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return deAt;
	
	})));


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

	//! moment.js locale configuration
	//! locale : German (Switzerland) [de-ch]
	//! author : sschueller : https://github.com/sschueller
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var deCh = moment.defineLocale('de-ch', {
	    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH.mm',
	        LTS: 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH.mm',
	        LLLL : 'dddd, D. MMMM YYYY HH.mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return deCh;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Maldivian [dv]
	//! author : Jawish Hameed : https://github.com/jawish
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'ޖެނުއަރީ',
	    'ފެބްރުއަރީ',
	    'މާރިޗު',
	    'އޭޕްރީލު',
	    'މޭ',
	    'ޖޫން',
	    'ޖުލައި',
	    'އޯގަސްޓު',
	    'ސެޕްޓެމްބަރު',
	    'އޮކްޓޯބަރު',
	    'ނޮވެމްބަރު',
	    'ޑިސެމްބަރު'
	];
	var weekdays = [
	    'އާދިއްތަ',
	    'ހޯމަ',
	    'އަންގާރަ',
	    'ބުދަ',
	    'ބުރާސްފަތި',
	    'ހުކުރު',
	    'ހޮނިހިރު'
	];
	
	var dv = moment.defineLocale('dv', {
	    months : months,
	    monthsShort : months,
	    weekdays : weekdays,
	    weekdaysShort : weekdays,
	    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),
	    longDateFormat : {
	
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/M/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /މކ|މފ/,
	    isPM : function (input) {
	        return 'މފ' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'މކ';
	        } else {
	            return 'މފ';
	        }
	    },
	    calendar : {
	        sameDay : '[މިއަދު] LT',
	        nextDay : '[މާދަމާ] LT',
	        nextWeek : 'dddd LT',
	        lastDay : '[އިއްޔެ] LT',
	        lastWeek : '[ފާއިތުވި] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ތެރޭގައި %s',
	        past : 'ކުރިން %s',
	        s : 'ސިކުންތުކޮޅެއް',
	        m : 'މިނިޓެއް',
	        mm : 'މިނިޓު %d',
	        h : 'ގަޑިއިރެއް',
	        hh : 'ގަޑިއިރު %d',
	        d : 'ދުވަހެއް',
	        dd : 'ދުވަސް %d',
	        M : 'މަހެއް',
	        MM : 'މަސް %d',
	        y : 'އަހަރެއް',
	        yy : 'އަހަރު %d'
	    },
	    preparse: function (string) {
	        return string.replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/,/g, '،');
	    },
	    week : {
	        dow : 7,  // Sunday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return dv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Greek [el]
	//! author : Aggelos Karalias : https://github.com/mehiel
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	function isFunction(input) {
	    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
	}
	
	
	var el = moment.defineLocale('el', {
	    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),
	    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),
	    months : function (momentToFormat, format) {
	        if (!momentToFormat) {
	            return this._monthsNominativeEl;
	        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'
	            return this._monthsGenitiveEl[momentToFormat.month()];
	        } else {
	            return this._monthsNominativeEl[momentToFormat.month()];
	        }
	    },
	    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
	    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),
	    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),
	    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'μμ' : 'ΜΜ';
	        } else {
	            return isLower ? 'πμ' : 'ΠΜ';
	        }
	    },
	    isPM : function (input) {
	        return ((input + '').toLowerCase()[0] === 'μ');
	    },
	    meridiemParse : /[ΠΜ]\.?Μ?\.?/i,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendarEl : {
	        sameDay : '[Σήμερα {}] LT',
	        nextDay : '[Αύριο {}] LT',
	        nextWeek : 'dddd [{}] LT',
	        lastDay : '[Χθες {}] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 6:
	                    return '[το προηγούμενο] dddd [{}] LT';
	                default:
	                    return '[την προηγούμενη] dddd [{}] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    calendar : function (key, mom) {
	        var output = this._calendarEl[key],
	            hours = mom && mom.hours();
	        if (isFunction(output)) {
	            output = output.apply(mom);
	        }
	        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));
	    },
	    relativeTime : {
	        future : 'σε %s',
	        past : '%s πριν',
	        s : 'λίγα δευτερόλεπτα',
	        m : 'ένα λεπτό',
	        mm : '%d λεπτά',
	        h : 'μία ώρα',
	        hh : '%d ώρες',
	        d : 'μία μέρα',
	        dd : '%d μέρες',
	        M : 'ένας μήνας',
	        MM : '%d μήνες',
	        y : 'ένας χρόνος',
	        yy : '%d χρόνια'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}η/,
	    ordinal: '%dη',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4st is the first week of the year.
	    }
	});
	
	return el;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (Australia) [en-au]
	//! author : Jared Morse : https://github.com/jarcoal
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enAu = moment.defineLocale('en-au', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enAu;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (Canada) [en-ca]
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enCa = moment.defineLocale('en-ca', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'YYYY-MM-DD',
	        LL : 'MMMM D, YYYY',
	        LLL : 'MMMM D, YYYY h:mm A',
	        LLLL : 'dddd, MMMM D, YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    }
	});
	
	return enCa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (United Kingdom) [en-gb]
	//! author : Chris Gedrim : https://github.com/chrisgedrim
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enGb = moment.defineLocale('en-gb', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enGb;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (Ireland) [en-ie]
	//! author : Chris Cartlidge : https://github.com/chriscartlidge
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enIe = moment.defineLocale('en-ie', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enIe;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (New Zealand) [en-nz]
	//! author : Luke McGregor : https://github.com/lukemcgregor
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enNz = moment.defineLocale('en-nz', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enNz;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Esperanto [eo]
	//! author : Colin Dean : https://github.com/colindean
	//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia
	//! comment : miestasmia corrected the translation by colindean
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var eo = moment.defineLocale('eo', {
	    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),
	    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),
	    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),
	    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D[-a de] MMMM, YYYY',
	        LLL : 'D[-a de] MMMM, YYYY HH:mm',
	        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'
	    },
	    meridiemParse: /[ap]\.t\.m/i,
	    isPM: function (input) {
	        return input.charAt(0).toLowerCase() === 'p';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'p.t.m.' : 'P.T.M.';
	        } else {
	            return isLower ? 'a.t.m.' : 'A.T.M.';
	        }
	    },
	    calendar : {
	        sameDay : '[Hodiaŭ je] LT',
	        nextDay : '[Morgaŭ je] LT',
	        nextWeek : 'dddd [je] LT',
	        lastDay : '[Hieraŭ je] LT',
	        lastWeek : '[pasinta] dddd [je] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'post %s',
	        past : 'antaŭ %s',
	        s : 'sekundoj',
	        m : 'minuto',
	        mm : '%d minutoj',
	        h : 'horo',
	        hh : '%d horoj',
	        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo
	        dd : '%d tagoj',
	        M : 'monato',
	        MM : '%d monatoj',
	        y : 'jaro',
	        yy : '%d jaroj'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}a/,
	    ordinal : '%da',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return eo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Spanish [es]
	//! author : Julio Napurí : https://github.com/julionc
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');
	var monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
	
	var es = moment.defineLocale('es', {
	    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortDot;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShort[m.month()];
	        } else {
	            return monthsShortDot[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY H:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastDay : function () {
	            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'en %s',
	        past : 'hace %s',
	        s : 'unos segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'una hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un año',
	        yy : '%d años'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return es;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Spanish (Dominican Republic) [es-do]
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');
	var monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
	
	var esDo = moment.defineLocale('es-do', {
	    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortDot;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShort[m.month()];
	        } else {
	            return monthsShortDot[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY h:mm A',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastDay : function () {
	            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'en %s',
	        past : 'hace %s',
	        s : 'unos segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'una hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un año',
	        yy : '%d años'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return esDo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Estonian [et]
	//! author : Henry Kehlmann : https://github.com/madhenry
	//! improvements : Illimar Tambek : https://github.com/ragulka
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
	        'm' : ['ühe minuti', 'üks minut'],
	        'mm': [number + ' minuti', number + ' minutit'],
	        'h' : ['ühe tunni', 'tund aega', 'üks tund'],
	        'hh': [number + ' tunni', number + ' tundi'],
	        'd' : ['ühe päeva', 'üks päev'],
	        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],
	        'MM': [number + ' kuu', number + ' kuud'],
	        'y' : ['ühe aasta', 'aasta', 'üks aasta'],
	        'yy': [number + ' aasta', number + ' aastat']
	    };
	    if (withoutSuffix) {
	        return format[key][2] ? format[key][2] : format[key][1];
	    }
	    return isFuture ? format[key][0] : format[key][1];
	}
	
	var et = moment.defineLocale('et', {
	    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),
	    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),
	    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),
	    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),
	    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),
	    longDateFormat : {
	        LT   : 'H:mm',
	        LTS : 'H:mm:ss',
	        L    : 'DD.MM.YYYY',
	        LL   : 'D. MMMM YYYY',
	        LLL  : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[Täna,] LT',
	        nextDay  : '[Homme,] LT',
	        nextWeek : '[Järgmine] dddd LT',
	        lastDay  : '[Eile,] LT',
	        lastWeek : '[Eelmine] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s pärast',
	        past   : '%s tagasi',
	        s      : processRelativeTime,
	        m      : processRelativeTime,
	        mm     : processRelativeTime,
	        h      : processRelativeTime,
	        hh     : processRelativeTime,
	        d      : processRelativeTime,
	        dd     : '%d päeva',
	        M      : processRelativeTime,
	        MM     : processRelativeTime,
	        y      : processRelativeTime,
	        yy     : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return et;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Basque [eu]
	//! author : Eneko Illarramendi : https://github.com/eillarra
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var eu = moment.defineLocale('eu', {
	    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),
	    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),
	    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),
	    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'YYYY[ko] MMMM[ren] D[a]',
	        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
	        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
	        l : 'YYYY-M-D',
	        ll : 'YYYY[ko] MMM D[a]',
	        lll : 'YYYY[ko] MMM D[a] HH:mm',
	        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
	    },
	    calendar : {
	        sameDay : '[gaur] LT[etan]',
	        nextDay : '[bihar] LT[etan]',
	        nextWeek : 'dddd LT[etan]',
	        lastDay : '[atzo] LT[etan]',
	        lastWeek : '[aurreko] dddd LT[etan]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s barru',
	        past : 'duela %s',
	        s : 'segundo batzuk',
	        m : 'minutu bat',
	        mm : '%d minutu',
	        h : 'ordu bat',
	        hh : '%d ordu',
	        d : 'egun bat',
	        dd : '%d egun',
	        M : 'hilabete bat',
	        MM : '%d hilabete',
	        y : 'urte bat',
	        yy : '%d urte'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return eu;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Persian [fa]
	//! author : Ebrahim Byagowi : https://github.com/ebraminio
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '۱',
	    '2': '۲',
	    '3': '۳',
	    '4': '۴',
	    '5': '۵',
	    '6': '۶',
	    '7': '۷',
	    '8': '۸',
	    '9': '۹',
	    '0': '۰'
	};
	var numberMap = {
	    '۱': '1',
	    '۲': '2',
	    '۳': '3',
	    '۴': '4',
	    '۵': '5',
	    '۶': '6',
	    '۷': '7',
	    '۸': '8',
	    '۹': '9',
	    '۰': '0'
	};
	
	var fa = moment.defineLocale('fa', {
	    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
	    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
	    weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
	    weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
	    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /قبل از ظهر|بعد از ظهر/,
	    isPM: function (input) {
	        return /بعد از ظهر/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'قبل از ظهر';
	        } else {
	            return 'بعد از ظهر';
	        }
	    },
	    calendar : {
	        sameDay : '[امروز ساعت] LT',
	        nextDay : '[فردا ساعت] LT',
	        nextWeek : 'dddd [ساعت] LT',
	        lastDay : '[دیروز ساعت] LT',
	        lastWeek : 'dddd [پیش] [ساعت] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'در %s',
	        past : '%s پیش',
	        s : 'چند ثانیه',
	        m : 'یک دقیقه',
	        mm : '%d دقیقه',
	        h : 'یک ساعت',
	        hh : '%d ساعت',
	        d : 'یک روز',
	        dd : '%d روز',
	        M : 'یک ماه',
	        MM : '%d ماه',
	        y : 'یک سال',
	        yy : '%d سال'
	    },
	    preparse: function (string) {
	        return string.replace(/[۰-۹]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}م/,
	    ordinal : '%dم',
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12 // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return fa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Finnish [fi]
	//! author : Tarmo Aidantausta : https://github.com/bleadof
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');
	var numbersFuture = [
	        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
	        numbersPast[7], numbersPast[8], numbersPast[9]
	    ];
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = '';
	    switch (key) {
	        case 's':
	            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
	        case 'm':
	            return isFuture ? 'minuutin' : 'minuutti';
	        case 'mm':
	            result = isFuture ? 'minuutin' : 'minuuttia';
	            break;
	        case 'h':
	            return isFuture ? 'tunnin' : 'tunti';
	        case 'hh':
	            result = isFuture ? 'tunnin' : 'tuntia';
	            break;
	        case 'd':
	            return isFuture ? 'päivän' : 'päivä';
	        case 'dd':
	            result = isFuture ? 'päivän' : 'päivää';
	            break;
	        case 'M':
	            return isFuture ? 'kuukauden' : 'kuukausi';
	        case 'MM':
	            result = isFuture ? 'kuukauden' : 'kuukautta';
	            break;
	        case 'y':
	            return isFuture ? 'vuoden' : 'vuosi';
	        case 'yy':
	            result = isFuture ? 'vuoden' : 'vuotta';
	            break;
	    }
	    result = verbalNumber(number, isFuture) + ' ' + result;
	    return result;
	}
	function verbalNumber(number, isFuture) {
	    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;
	}
	
	var fi = moment.defineLocale('fi', {
	    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),
	    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),
	    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),
	    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),
	    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'Do MMMM[ta] YYYY',
	        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
	        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
	        l : 'D.M.YYYY',
	        ll : 'Do MMM YYYY',
	        lll : 'Do MMM YYYY, [klo] HH.mm',
	        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
	    },
	    calendar : {
	        sameDay : '[tänään] [klo] LT',
	        nextDay : '[huomenna] [klo] LT',
	        nextWeek : 'dddd [klo] LT',
	        lastDay : '[eilen] [klo] LT',
	        lastWeek : '[viime] dddd[na] [klo] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s päästä',
	        past : '%s sitten',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Faroese [fo]
	//! author : Ragnar Johannesen : https://github.com/ragnar123
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var fo = moment.defineLocale('fo', {
	    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
	    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),
	    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),
	    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D. MMMM, YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Í dag kl.] LT',
	        nextDay : '[Í morgin kl.] LT',
	        nextWeek : 'dddd [kl.] LT',
	        lastDay : '[Í gjár kl.] LT',
	        lastWeek : '[síðstu] dddd [kl] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'um %s',
	        past : '%s síðani',
	        s : 'fá sekund',
	        m : 'ein minutt',
	        mm : '%d minuttir',
	        h : 'ein tími',
	        hh : '%d tímar',
	        d : 'ein dagur',
	        dd : '%d dagar',
	        M : 'ein mánaði',
	        MM : '%d mánaðir',
	        y : 'eitt ár',
	        yy : '%d ár'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : French [fr]
	//! author : John Fischer : https://github.com/jfroffice
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var fr = moment.defineLocale('fr', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Aujourd’hui à] LT',
	        nextDay : '[Demain à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[Hier à] LT',
	        lastWeek : 'dddd [dernier à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // TODO: Return 'e' when day of month > 1. Move this case inside
	            // block for masculine words below.
	            // See https://github.com/moment/moment/issues/3375
	            case 'D':
	                return number + (number === 1 ? 'er' : '');
	
	            // Words with masculine grammatical gender: mois, trimestre, jour
	            default:
	            case 'M':
	            case 'Q':
	            case 'DDD':
	            case 'd':
	                return number + (number === 1 ? 'er' : 'e');
	
	            // Words with feminine grammatical gender: semaine
	            case 'w':
	            case 'W':
	                return number + (number === 1 ? 're' : 'e');
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : French (Canada) [fr-ca]
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var frCa = moment.defineLocale('fr-ca', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Aujourd’hui à] LT',
	        nextDay : '[Demain à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[Hier à] LT',
	        lastWeek : 'dddd [dernier à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // Words with masculine grammatical gender: mois, trimestre, jour
	            default:
	            case 'M':
	            case 'Q':
	            case 'D':
	            case 'DDD':
	            case 'd':
	                return number + (number === 1 ? 'er' : 'e');
	
	            // Words with feminine grammatical gender: semaine
	            case 'w':
	            case 'W':
	                return number + (number === 1 ? 're' : 'e');
	        }
	    }
	});
	
	return frCa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : French (Switzerland) [fr-ch]
	//! author : Gaspard Bucher : https://github.com/gaspard
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var frCh = moment.defineLocale('fr-ch', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Aujourd’hui à] LT',
	        nextDay : '[Demain à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[Hier à] LT',
	        lastWeek : 'dddd [dernier à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // Words with masculine grammatical gender: mois, trimestre, jour
	            default:
	            case 'M':
	            case 'Q':
	            case 'D':
	            case 'DDD':
	            case 'd':
	                return number + (number === 1 ? 'er' : 'e');
	
	            // Words with feminine grammatical gender: semaine
	            case 'w':
	            case 'W':
	                return number + (number === 1 ? 're' : 'e');
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return frCh;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Frisian [fy]
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');
	
	var fy = moment.defineLocale('fy', {
	    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortWithDots;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),
	    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),
	    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[hjoed om] LT',
	        nextDay: '[moarn om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[juster om] LT',
	        lastWeek: '[ôfrûne] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'oer %s',
	        past : '%s lyn',
	        s : 'in pear sekonden',
	        m : 'ien minút',
	        mm : '%d minuten',
	        h : 'ien oere',
	        hh : '%d oeren',
	        d : 'ien dei',
	        dd : '%d dagen',
	        M : 'ien moanne',
	        MM : '%d moannen',
	        y : 'ien jier',
	        yy : '%d jierren'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Scottish Gaelic [gd]
	//! author : Jon Ashdown : https://github.com/jonashdown
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'
	];
	
	var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];
	
	var weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];
	
	var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];
	
	var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];
	
	var gd = moment.defineLocale('gd', {
	    months : months,
	    monthsShort : monthsShort,
	    monthsParseExact : true,
	    weekdays : weekdays,
	    weekdaysShort : weekdaysShort,
	    weekdaysMin : weekdaysMin,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[An-diugh aig] LT',
	        nextDay : '[A-màireach aig] LT',
	        nextWeek : 'dddd [aig] LT',
	        lastDay : '[An-dè aig] LT',
	        lastWeek : 'dddd [seo chaidh] [aig] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ann an %s',
	        past : 'bho chionn %s',
	        s : 'beagan diogan',
	        m : 'mionaid',
	        mm : '%d mionaidean',
	        h : 'uair',
	        hh : '%d uairean',
	        d : 'latha',
	        dd : '%d latha',
	        M : 'mìos',
	        MM : '%d mìosan',
	        y : 'bliadhna',
	        yy : '%d bliadhna'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}(d|na|mh)/,
	    ordinal : function (number) {
	        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return gd;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Galician [gl]
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var gl = moment.defineLocale('gl', {
	    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),
	    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY H:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
	        },
	        lastDay : function () {
	            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';
	        },
	        lastWeek : function () {
	            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : function (str) {
	            if (str.indexOf('un') === 0) {
	                return 'n' + str;
	            }
	            return 'en ' + str;
	        },
	        past : 'hai %s',
	        s : 'uns segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'unha hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un ano',
	        yy : '%d anos'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return gl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Konkani Latin script [gom-latn]
	//! author : The Discoverer : https://github.com/WikiDiscoverer
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's': ['thodde secondanim', 'thodde second'],
	        'm': ['eka mintan', 'ek minute'],
	        'mm': [number + ' mintanim', number + ' mintam'],
	        'h': ['eka horan', 'ek hor'],
	        'hh': [number + ' horanim', number + ' hor'],
	        'd': ['eka disan', 'ek dis'],
	        'dd': [number + ' disanim', number + ' dis'],
	        'M': ['eka mhoinean', 'ek mhoino'],
	        'MM': [number + ' mhoineanim', number + ' mhoine'],
	        'y': ['eka vorsan', 'ek voros'],
	        'yy': [number + ' vorsanim', number + ' vorsam']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var gomLatn = moment.defineLocale('gom-latn', {
	    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),
	    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\'var'.split('_'),
	    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),
	    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'A h:mm [vazta]',
	        LTS : 'A h:mm:ss [vazta]',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY A h:mm [vazta]',
	        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',
	        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'
	    },
	    calendar : {
	        sameDay: '[Aiz] LT',
	        nextDay: '[Faleam] LT',
	        nextWeek: '[Ieta to] dddd[,] LT',
	        lastDay: '[Kal] LT',
	        lastWeek: '[Fatlo] dddd[,] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s',
	        past : '%s adim',
	        s : processRelativeTime,
	        m : processRelativeTime,
	        mm : processRelativeTime,
	        h : processRelativeTime,
	        hh : processRelativeTime,
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}(er)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // the ordinal 'er' only applies to day of the month
	            case 'D':
	                return number + 'er';
	            default:
	            case 'M':
	            case 'Q':
	            case 'DDD':
	            case 'd':
	            case 'w':
	            case 'W':
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    },
	    meridiemParse: /rati|sokalli|donparam|sanje/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'rati') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'sokalli') {
	            return hour;
	        } else if (meridiem === 'donparam') {
	            return hour > 12 ? hour : hour + 12;
	        } else if (meridiem === 'sanje') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'rati';
	        } else if (hour < 12) {
	            return 'sokalli';
	        } else if (hour < 16) {
	            return 'donparam';
	        } else if (hour < 20) {
	            return 'sanje';
	        } else {
	            return 'rati';
	        }
	    }
	});
	
	return gomLatn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Hebrew [he]
	//! author : Tomer Cohen : https://github.com/tomer
	//! author : Moshe Simantov : https://github.com/DevelopmentIL
	//! author : Tal Ater : https://github.com/TalAter
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var he = moment.defineLocale('he', {
	    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),
	    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),
	    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),
	    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),
	    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [ב]MMMM YYYY',
	        LLL : 'D [ב]MMMM YYYY HH:mm',
	        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
	        l : 'D/M/YYYY',
	        ll : 'D MMM YYYY',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd, D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[היום ב־]LT',
	        nextDay : '[מחר ב־]LT',
	        nextWeek : 'dddd [בשעה] LT',
	        lastDay : '[אתמול ב־]LT',
	        lastWeek : '[ביום] dddd [האחרון בשעה] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'בעוד %s',
	        past : 'לפני %s',
	        s : 'מספר שניות',
	        m : 'דקה',
	        mm : '%d דקות',
	        h : 'שעה',
	        hh : function (number) {
	            if (number === 2) {
	                return 'שעתיים';
	            }
	            return number + ' שעות';
	        },
	        d : 'יום',
	        dd : function (number) {
	            if (number === 2) {
	                return 'יומיים';
	            }
	            return number + ' ימים';
	        },
	        M : 'חודש',
	        MM : function (number) {
	            if (number === 2) {
	                return 'חודשיים';
	            }
	            return number + ' חודשים';
	        },
	        y : 'שנה',
	        yy : function (number) {
	            if (number === 2) {
	                return 'שנתיים';
	            } else if (number % 10 === 0 && number !== 10) {
	                return number + ' שנה';
	            }
	            return number + ' שנים';
	        }
	    },
	    meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,
	    isPM : function (input) {
	        return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 5) {
	            return 'לפנות בוקר';
	        } else if (hour < 10) {
	            return 'בבוקר';
	        } else if (hour < 12) {
	            return isLower ? 'לפנה"צ' : 'לפני הצהריים';
	        } else if (hour < 18) {
	            return isLower ? 'אחה"צ' : 'אחרי הצהריים';
	        } else {
	            return 'בערב';
	        }
	    }
	});
	
	return he;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Hindi [hi]
	//! author : Mayank Singhal : https://github.com/mayanksinghal
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	var hi = moment.defineLocale('hi', {
	    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),
	    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
	    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),
	    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm बजे',
	        LTS : 'A h:mm:ss बजे',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm बजे',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[कल] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[कल] LT',
	        lastWeek : '[पिछले] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s में',
	        past : '%s पहले',
	        s : 'कुछ ही क्षण',
	        m : 'एक मिनट',
	        mm : '%d मिनट',
	        h : 'एक घंटा',
	        hh : '%d घंटे',
	        d : 'एक दिन',
	        dd : '%d दिन',
	        M : 'एक महीने',
	        MM : '%d महीने',
	        y : 'एक वर्ष',
	        yy : '%d वर्ष'
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // Hindi notation for meridiems are quite fuzzy in practice. While there exists
	    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
	    meridiemParse: /रात|सुबह|दोपहर|शाम/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'रात') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'सुबह') {
	            return hour;
	        } else if (meridiem === 'दोपहर') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'शाम') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'रात';
	        } else if (hour < 10) {
	            return 'सुबह';
	        } else if (hour < 17) {
	            return 'दोपहर';
	        } else if (hour < 20) {
	            return 'शाम';
	        } else {
	            return 'रात';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return hi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Croatian [hr]
	//! author : Bojan Marković : https://github.com/bmarkovic
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
	        case 'mm':
	            if (number === 1) {
	                result += 'minuta';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'minute';
	            } else {
	                result += 'minuta';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'jedan sat' : 'jednog sata';
	        case 'hh':
	            if (number === 1) {
	                result += 'sat';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'sata';
	            } else {
	                result += 'sati';
	            }
	            return result;
	        case 'dd':
	            if (number === 1) {
	                result += 'dan';
	            } else {
	                result += 'dana';
	            }
	            return result;
	        case 'MM':
	            if (number === 1) {
	                result += 'mjesec';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'mjeseca';
	            } else {
	                result += 'mjeseci';
	            }
	            return result;
	        case 'yy':
	            if (number === 1) {
	                result += 'godina';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'godine';
	            } else {
	                result += 'godina';
	            }
	            return result;
	    }
	}
	
	var hr = moment.defineLocale('hr', {
	    months : {
	        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),
	        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')
	    },
	    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danas u] LT',
	        nextDay  : '[sutra u] LT',
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[jučer u] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                    return '[prošlu] dddd [u] LT';
	                case 6:
	                    return '[prošle] [subote] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prošli] dddd [u] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'par sekundi',
	        m      : translate,
	        mm     : translate,
	        h      : translate,
	        hh     : translate,
	        d      : 'dan',
	        dd     : translate,
	        M      : 'mjesec',
	        MM     : translate,
	        y      : 'godinu',
	        yy     : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return hr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Hungarian [hu]
	//! author : Adam Brunner : https://github.com/adambrunner
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
	function translate(number, withoutSuffix, key, isFuture) {
	    var num = number,
	        suffix;
	    switch (key) {
	        case 's':
	            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
	        case 'm':
	            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
	        case 'mm':
	            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
	        case 'h':
	            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
	        case 'hh':
	            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
	        case 'd':
	            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
	        case 'dd':
	            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
	        case 'M':
	            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
	        case 'MM':
	            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
	        case 'y':
	            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
	        case 'yy':
	            return num + (isFuture || withoutSuffix ? ' év' : ' éve');
	    }
	    return '';
	}
	function week(isFuture) {
	    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
	}
	
	var hu = moment.defineLocale('hu', {
	    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),
	    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),
	    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),
	    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),
	    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'YYYY.MM.DD.',
	        LL : 'YYYY. MMMM D.',
	        LLL : 'YYYY. MMMM D. H:mm',
	        LLLL : 'YYYY. MMMM D., dddd H:mm'
	    },
	    meridiemParse: /de|du/i,
	    isPM: function (input) {
	        return input.charAt(1).toLowerCase() === 'u';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower === true ? 'de' : 'DE';
	        } else {
	            return isLower === true ? 'du' : 'DU';
	        }
	    },
	    calendar : {
	        sameDay : '[ma] LT[-kor]',
	        nextDay : '[holnap] LT[-kor]',
	        nextWeek : function () {
	            return week.call(this, true);
	        },
	        lastDay : '[tegnap] LT[-kor]',
	        lastWeek : function () {
	            return week.call(this, false);
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s múlva',
	        past : '%s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return hu;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Armenian [hy-am]
	//! author : Armendarabyan : https://github.com/armendarabyan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var hyAm = moment.defineLocale('hy-am', {
	    months : {
	        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),
	        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')
	    },
	    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),
	    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),
	    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
	    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY թ.',
	        LLL : 'D MMMM YYYY թ., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'
	    },
	    calendar : {
	        sameDay: '[այսօր] LT',
	        nextDay: '[վաղը] LT',
	        lastDay: '[երեկ] LT',
	        nextWeek: function () {
	            return 'dddd [օրը ժամը] LT';
	        },
	        lastWeek: function () {
	            return '[անցած] dddd [օրը ժամը] LT';
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s հետո',
	        past : '%s առաջ',
	        s : 'մի քանի վայրկյան',
	        m : 'րոպե',
	        mm : '%d րոպե',
	        h : 'ժամ',
	        hh : '%d ժամ',
	        d : 'օր',
	        dd : '%d օր',
	        M : 'ամիս',
	        MM : '%d ամիս',
	        y : 'տարի',
	        yy : '%d տարի'
	    },
	    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,
	    isPM: function (input) {
	        return /^(ցերեկվա|երեկոյան)$/.test(input);
	    },
	    meridiem : function (hour) {
	        if (hour < 4) {
	            return 'գիշերվա';
	        } else if (hour < 12) {
	            return 'առավոտվա';
	        } else if (hour < 17) {
	            return 'ցերեկվա';
	        } else {
	            return 'երեկոյան';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'DDD':
	            case 'w':
	            case 'W':
	            case 'DDDo':
	                if (number === 1) {
	                    return number + '-ին';
	                }
	                return number + '-րդ';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return hyAm;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Indonesian [id]
	//! author : Mohammad Satrio Utomo : https://github.com/tyok
	//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var id = moment.defineLocale('id', {
	    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),
	    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),
	    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|siang|sore|malam/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'siang') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'sore' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'siang';
	        } else if (hours < 19) {
	            return 'sore';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Besok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kemarin pukul] LT',
	        lastWeek : 'dddd [lalu pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lalu',
	        s : 'beberapa detik',
	        m : 'semenit',
	        mm : '%d menit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return id;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Icelandic [is]
	//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(n) {
	    if (n % 100 === 11) {
	        return true;
	    } else if (n % 10 === 1) {
	        return false;
	    }
	    return true;
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':
	            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';
	        case 'm':
	            return withoutSuffix ? 'mínúta' : 'mínútu';
	        case 'mm':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');
	            } else if (withoutSuffix) {
	                return result + 'mínúta';
	            }
	            return result + 'mínútu';
	        case 'hh':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');
	            }
	            return result + 'klukkustund';
	        case 'd':
	            if (withoutSuffix) {
	                return 'dagur';
	            }
	            return isFuture ? 'dag' : 'degi';
	        case 'dd':
	            if (plural(number)) {
	                if (withoutSuffix) {
	                    return result + 'dagar';
	                }
	                return result + (isFuture ? 'daga' : 'dögum');
	            } else if (withoutSuffix) {
	                return result + 'dagur';
	            }
	            return result + (isFuture ? 'dag' : 'degi');
	        case 'M':
	            if (withoutSuffix) {
	                return 'mánuður';
	            }
	            return isFuture ? 'mánuð' : 'mánuði';
	        case 'MM':
	            if (plural(number)) {
	                if (withoutSuffix) {
	                    return result + 'mánuðir';
	                }
	                return result + (isFuture ? 'mánuði' : 'mánuðum');
	            } else if (withoutSuffix) {
	                return result + 'mánuður';
	            }
	            return result + (isFuture ? 'mánuð' : 'mánuði');
	        case 'y':
	            return withoutSuffix || isFuture ? 'ár' : 'ári';
	        case 'yy':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
	            }
	            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
	    }
	}
	
	var is = moment.defineLocale('is', {
	    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),
	    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),
	    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),
	    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] H:mm',
	        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
	    },
	    calendar : {
	        sameDay : '[í dag kl.] LT',
	        nextDay : '[á morgun kl.] LT',
	        nextWeek : 'dddd [kl.] LT',
	        lastDay : '[í gær kl.] LT',
	        lastWeek : '[síðasta] dddd [kl.] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'eftir %s',
	        past : 'fyrir %s síðan',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : 'klukkustund',
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return is;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Italian [it]
	//! author : Lorenzo : https://github.com/aliem
	//! author: Mattia Larentis: https://github.com/nostalgiaz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var it = moment.defineLocale('it', {
	    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),
	    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
	    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),
	    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
	    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Oggi alle] LT',
	        nextDay: '[Domani alle] LT',
	        nextWeek: 'dddd [alle] LT',
	        lastDay: '[Ieri alle] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[la scorsa] dddd [alle] LT';
	                default:
	                    return '[lo scorso] dddd [alle] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : function (s) {
	            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;
	        },
	        past : '%s fa',
	        s : 'alcuni secondi',
	        m : 'un minuto',
	        mm : '%d minuti',
	        h : 'un\'ora',
	        hh : '%d ore',
	        d : 'un giorno',
	        dd : '%d giorni',
	        M : 'un mese',
	        MM : '%d mesi',
	        y : 'un anno',
	        yy : '%d anni'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal: '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return it;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Japanese [ja]
	//! author : LI Long : https://github.com/baryon
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ja = moment.defineLocale('ja', {
	    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
	    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),
	    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY/MM/DD',
	        LL : 'YYYY年M月D日',
	        LLL : 'YYYY年M月D日 HH:mm',
	        LLLL : 'YYYY年M月D日 HH:mm dddd',
	        l : 'YYYY/MM/DD',
	        ll : 'YYYY年M月D日',
	        lll : 'YYYY年M月D日 HH:mm',
	        llll : 'YYYY年M月D日 HH:mm dddd'
	    },
	    meridiemParse: /午前|午後/i,
	    isPM : function (input) {
	        return input === '午後';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return '午前';
	        } else {
	            return '午後';
	        }
	    },
	    calendar : {
	        sameDay : '[今日] LT',
	        nextDay : '[明日] LT',
	        nextWeek : '[来週]dddd LT',
	        lastDay : '[昨日] LT',
	        lastWeek : '[前週]dddd LT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}日/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd':
	            case 'D':
	            case 'DDD':
	                return number + '日';
	            default:
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s後',
	        past : '%s前',
	        s : '数秒',
	        m : '1分',
	        mm : '%d分',
	        h : '1時間',
	        hh : '%d時間',
	        d : '1日',
	        dd : '%d日',
	        M : '1ヶ月',
	        MM : '%dヶ月',
	        y : '1年',
	        yy : '%d年'
	    }
	});
	
	return ja;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Javanese [jv]
	//! author : Rony Lantip : https://github.com/lantip
	//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var jv = moment.defineLocale('jv', {
	    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),
	    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),
	    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),
	    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /enjing|siyang|sonten|ndalu/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'enjing') {
	            return hour;
	        } else if (meridiem === 'siyang') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'enjing';
	        } else if (hours < 15) {
	            return 'siyang';
	        } else if (hours < 19) {
	            return 'sonten';
	        } else {
	            return 'ndalu';
	        }
	    },
	    calendar : {
	        sameDay : '[Dinten puniko pukul] LT',
	        nextDay : '[Mbenjang pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kala wingi pukul] LT',
	        lastWeek : 'dddd [kepengker pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'wonten ing %s',
	        past : '%s ingkang kepengker',
	        s : 'sawetawis detik',
	        m : 'setunggal menit',
	        mm : '%d menit',
	        h : 'setunggal jam',
	        hh : '%d jam',
	        d : 'sedinten',
	        dd : '%d dinten',
	        M : 'sewulan',
	        MM : '%d wulan',
	        y : 'setaun',
	        yy : '%d taun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return jv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Georgian [ka]
	//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ka = moment.defineLocale('ka', {
	    months : {
	        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
	        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')
	    },
	    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),
	    weekdays : {
	        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),
	        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),
	        isFormat: /(წინა|შემდეგ)/
	    },
	    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),
	    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[დღეს] LT[-ზე]',
	        nextDay : '[ხვალ] LT[-ზე]',
	        lastDay : '[გუშინ] LT[-ზე]',
	        nextWeek : '[შემდეგ] dddd LT[-ზე]',
	        lastWeek : '[წინა] dddd LT-ზე',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : function (s) {
	            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?
	                s.replace(/ი$/, 'ში') :
	                s + 'ში';
	        },
	        past : function (s) {
	            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {
	                return s.replace(/(ი|ე)$/, 'ის უკან');
	            }
	            if ((/წელი/).test(s)) {
	                return s.replace(/წელი$/, 'წლის უკან');
	            }
	        },
	        s : 'რამდენიმე წამი',
	        m : 'წუთი',
	        mm : '%d წუთი',
	        h : 'საათი',
	        hh : '%d საათი',
	        d : 'დღე',
	        dd : '%d დღე',
	        M : 'თვე',
	        MM : '%d თვე',
	        y : 'წელი',
	        yy : '%d წელი'
	    },
	    dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,
	    ordinal : function (number) {
	        if (number === 0) {
	            return number;
	        }
	        if (number === 1) {
	            return number + '-ლი';
	        }
	        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {
	            return 'მე-' + number;
	        }
	        return number + '-ე';
	    },
	    week : {
	        dow : 1,
	        doy : 7
	    }
	});
	
	return ka;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Kazakh [kk]
	//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    0: '-ші',
	    1: '-ші',
	    2: '-ші',
	    3: '-ші',
	    4: '-ші',
	    5: '-ші',
	    6: '-шы',
	    7: '-ші',
	    8: '-ші',
	    9: '-шы',
	    10: '-шы',
	    20: '-шы',
	    30: '-шы',
	    40: '-шы',
	    50: '-ші',
	    60: '-шы',
	    70: '-ші',
	    80: '-ші',
	    90: '-шы',
	    100: '-ші'
	};
	
	var kk = moment.defineLocale('kk', {
	    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),
	    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),
	    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),
	    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),
	    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бүгін сағат] LT',
	        nextDay : '[Ертең сағат] LT',
	        nextWeek : 'dddd [сағат] LT',
	        lastDay : '[Кеше сағат] LT',
	        lastWeek : '[Өткен аптаның] dddd [сағат] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ішінде',
	        past : '%s бұрын',
	        s : 'бірнеше секунд',
	        m : 'бір минут',
	        mm : '%d минут',
	        h : 'бір сағат',
	        hh : '%d сағат',
	        d : 'бір күн',
	        dd : '%d күн',
	        M : 'бір ай',
	        MM : '%d ай',
	        y : 'бір жыл',
	        yy : '%d жыл'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/,
	    ordinal : function (number) {
	        var a = number % 10,
	            b = number >= 100 ? 100 : null;
	        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return kk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Cambodian [km]
	//! author : Kruy Vanna : https://github.com/kruyvanna
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var km = moment.defineLocale('km', {
	    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
	    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
	    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',
	        nextDay: '[ស្អែក ម៉ោង] LT',
	        nextWeek: 'dddd [ម៉ោង] LT',
	        lastDay: '[ម្សិលមិញ ម៉ោង] LT',
	        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: '%sទៀត',
	        past: '%sមុន',
	        s: 'ប៉ុន្មានវិនាទី',
	        m: 'មួយនាទី',
	        mm: '%d នាទី',
	        h: 'មួយម៉ោង',
	        hh: '%d ម៉ោង',
	        d: 'មួយថ្ងៃ',
	        dd: '%d ថ្ងៃ',
	        M: 'មួយខែ',
	        MM: '%d ខែ',
	        y: 'មួយឆ្នាំ',
	        yy: '%d ឆ្នាំ'
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return km;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Kannada [kn]
	//! author : Rajeev Naik : https://github.com/rajeevnaikte
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '೧',
	    '2': '೨',
	    '3': '೩',
	    '4': '೪',
	    '5': '೫',
	    '6': '೬',
	    '7': '೭',
	    '8': '೮',
	    '9': '೯',
	    '0': '೦'
	};
	var numberMap = {
	    '೧': '1',
	    '೨': '2',
	    '೩': '3',
	    '೪': '4',
	    '೫': '5',
	    '೬': '6',
	    '೭': '7',
	    '೮': '8',
	    '೯': '9',
	    '೦': '0'
	};
	
	var kn = moment.defineLocale('kn', {
	    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),
	    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),
	    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),
	    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[ಇಂದು] LT',
	        nextDay : '[ನಾಳೆ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ನಿನ್ನೆ] LT',
	        lastWeek : '[ಕೊನೆಯ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ನಂತರ',
	        past : '%s ಹಿಂದೆ',
	        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',
	        m : 'ಒಂದು ನಿಮಿಷ',
	        mm : '%d ನಿಮಿಷ',
	        h : 'ಒಂದು ಗಂಟೆ',
	        hh : '%d ಗಂಟೆ',
	        d : 'ಒಂದು ದಿನ',
	        dd : '%d ದಿನ',
	        M : 'ಒಂದು ತಿಂಗಳು',
	        MM : '%d ತಿಂಗಳು',
	        y : 'ಒಂದು ವರ್ಷ',
	        yy : '%d ವರ್ಷ'
	    },
	    preparse: function (string) {
	        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ರಾತ್ರಿ') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {
	            return hour;
	        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'ಸಂಜೆ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ರಾತ್ರಿ';
	        } else if (hour < 10) {
	            return 'ಬೆಳಿಗ್ಗೆ';
	        } else if (hour < 17) {
	            return 'ಮಧ್ಯಾಹ್ನ';
	        } else if (hour < 20) {
	            return 'ಸಂಜೆ';
	        } else {
	            return 'ರಾತ್ರಿ';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/,
	    ordinal : function (number) {
	        return number + 'ನೇ';
	    },
	    week : {
	        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.
	    }
	});
	
	return kn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Korean [ko]
	//! author : Kyungwook, Park : https://github.com/kyungw00k
	//! author : Jeeeyul Lee <jeeeyul@gmail.com>
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ko = moment.defineLocale('ko', {
	    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
	    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
	    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),
	    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),
	    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'YYYY.MM.DD',
	        LL : 'YYYY년 MMMM D일',
	        LLL : 'YYYY년 MMMM D일 A h:mm',
	        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',
	        l : 'YYYY.MM.DD',
	        ll : 'YYYY년 MMMM D일',
	        lll : 'YYYY년 MMMM D일 A h:mm',
	        llll : 'YYYY년 MMMM D일 dddd A h:mm'
	    },
	    calendar : {
	        sameDay : '오늘 LT',
	        nextDay : '내일 LT',
	        nextWeek : 'dddd LT',
	        lastDay : '어제 LT',
	        lastWeek : '지난주 dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s 후',
	        past : '%s 전',
	        s : '몇 초',
	        ss : '%d초',
	        m : '1분',
	        mm : '%d분',
	        h : '한 시간',
	        hh : '%d시간',
	        d : '하루',
	        dd : '%d일',
	        M : '한 달',
	        MM : '%d달',
	        y : '일 년',
	        yy : '%d년'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}일/,
	    ordinal : '%d일',
	    meridiemParse : /오전|오후/,
	    isPM : function (token) {
	        return token === '오후';
	    },
	    meridiem : function (hour, minute, isUpper) {
	        return hour < 12 ? '오전' : '오후';
	    }
	});
	
	return ko;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Kyrgyz [ky]
	//! author : Chyngyz Arystan uulu : https://github.com/chyngyz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var suffixes = {
	    0: '-чү',
	    1: '-чи',
	    2: '-чи',
	    3: '-чү',
	    4: '-чү',
	    5: '-чи',
	    6: '-чы',
	    7: '-чи',
	    8: '-чи',
	    9: '-чу',
	    10: '-чу',
	    20: '-чы',
	    30: '-чу',
	    40: '-чы',
	    50: '-чү',
	    60: '-чы',
	    70: '-чи',
	    80: '-чи',
	    90: '-чу',
	    100: '-чү'
	};
	
	var ky = moment.defineLocale('ky', {
	    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
	    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),
	    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),
	    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),
	    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бүгүн саат] LT',
	        nextDay : '[Эртең саат] LT',
	        nextWeek : 'dddd [саат] LT',
	        lastDay : '[Кече саат] LT',
	        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ичинде',
	        past : '%s мурун',
	        s : 'бирнече секунд',
	        m : 'бир мүнөт',
	        mm : '%d мүнөт',
	        h : 'бир саат',
	        hh : '%d саат',
	        d : 'бир күн',
	        dd : '%d күн',
	        M : 'бир ай',
	        MM : '%d ай',
	        y : 'бир жыл',
	        yy : '%d жыл'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/,
	    ordinal : function (number) {
	        var a = number % 10,
	            b = number >= 100 ? 100 : null;
	        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ky;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Luxembourgish [lb]
	//! author : mweimerskirch : https://github.com/mweimerskirch
	//! author : David Raison : https://github.com/kwisatz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eng Minutt', 'enger Minutt'],
	        'h': ['eng Stonn', 'enger Stonn'],
	        'd': ['een Dag', 'engem Dag'],
	        'M': ['ee Mount', 'engem Mount'],
	        'y': ['ee Joer', 'engem Joer']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	function processFutureTime(string) {
	    var number = string.substr(0, string.indexOf(' '));
	    if (eifelerRegelAppliesToNumber(number)) {
	        return 'a ' + string;
	    }
	    return 'an ' + string;
	}
	function processPastTime(string) {
	    var number = string.substr(0, string.indexOf(' '));
	    if (eifelerRegelAppliesToNumber(number)) {
	        return 'viru ' + string;
	    }
	    return 'virun ' + string;
	}
	/**
	 * Returns true if the word before the given number loses the '-n' ending.
	 * e.g. 'an 10 Deeg' but 'a 5 Deeg'
	 *
	 * @param number {integer}
	 * @returns {boolean}
	 */
	function eifelerRegelAppliesToNumber(number) {
	    number = parseInt(number, 10);
	    if (isNaN(number)) {
	        return false;
	    }
	    if (number < 0) {
	        // Negative Number --> always true
	        return true;
	    } else if (number < 10) {
	        // Only 1 digit
	        if (4 <= number && number <= 7) {
	            return true;
	        }
	        return false;
	    } else if (number < 100) {
	        // 2 digits
	        var lastDigit = number % 10, firstDigit = number / 10;
	        if (lastDigit === 0) {
	            return eifelerRegelAppliesToNumber(firstDigit);
	        }
	        return eifelerRegelAppliesToNumber(lastDigit);
	    } else if (number < 10000) {
	        // 3 or 4 digits --> recursively check first digit
	        while (number >= 10) {
	            number = number / 10;
	        }
	        return eifelerRegelAppliesToNumber(number);
	    } else {
	        // Anything larger than 4 digits: recursively check first n-3 digits
	        number = number / 1000;
	        return eifelerRegelAppliesToNumber(number);
	    }
	}
	
	var lb = moment.defineLocale('lb', {
	    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),
	    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),
	    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm [Auer]',
	        LTS: 'H:mm:ss [Auer]',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm [Auer]',
	        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
	    },
	    calendar: {
	        sameDay: '[Haut um] LT',
	        sameElse: 'L',
	        nextDay: '[Muer um] LT',
	        nextWeek: 'dddd [um] LT',
	        lastDay: '[Gëschter um] LT',
	        lastWeek: function () {
	            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule
	            switch (this.day()) {
	                case 2:
	                case 4:
	                    return '[Leschten] dddd [um] LT';
	                default:
	                    return '[Leschte] dddd [um] LT';
	            }
	        }
	    },
	    relativeTime : {
	        future : processFutureTime,
	        past : processPastTime,
	        s : 'e puer Sekonnen',
	        m : processRelativeTime,
	        mm : '%d Minutten',
	        h : processRelativeTime,
	        hh : '%d Stonnen',
	        d : processRelativeTime,
	        dd : '%d Deeg',
	        M : processRelativeTime,
	        MM : '%d Méint',
	        y : processRelativeTime,
	        yy : '%d Joer'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal: '%d.',
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lb;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Lao [lo]
	//! author : Ryan Hart : https://github.com/ryanhart2
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var lo = moment.defineLocale('lo', {
	    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),
	    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),
	    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
	    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
	    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,
	    isPM: function (input) {
	        return input === 'ຕອນແລງ';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ຕອນເຊົ້າ';
	        } else {
	            return 'ຕອນແລງ';
	        }
	    },
	    calendar : {
	        sameDay : '[ມື້ນີ້ເວລາ] LT',
	        nextDay : '[ມື້ອື່ນເວລາ] LT',
	        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',
	        lastDay : '[ມື້ວານນີ້ເວລາ] LT',
	        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ອີກ %s',
	        past : '%sຜ່ານມາ',
	        s : 'ບໍ່ເທົ່າໃດວິນາທີ',
	        m : '1 ນາທີ',
	        mm : '%d ນາທີ',
	        h : '1 ຊົ່ວໂມງ',
	        hh : '%d ຊົ່ວໂມງ',
	        d : '1 ມື້',
	        dd : '%d ມື້',
	        M : '1 ເດືອນ',
	        MM : '%d ເດືອນ',
	        y : '1 ປີ',
	        yy : '%d ປີ'
	    },
	    dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/,
	    ordinal : function (number) {
	        return 'ທີ່' + number;
	    }
	});
	
	return lo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Lithuanian [lt]
	//! author : Mindaugas Mozūras : https://github.com/mmozuras
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var units = {
	    'm' : 'minutė_minutės_minutę',
	    'mm': 'minutės_minučių_minutes',
	    'h' : 'valanda_valandos_valandą',
	    'hh': 'valandos_valandų_valandas',
	    'd' : 'diena_dienos_dieną',
	    'dd': 'dienos_dienų_dienas',
	    'M' : 'mėnuo_mėnesio_mėnesį',
	    'MM': 'mėnesiai_mėnesių_mėnesius',
	    'y' : 'metai_metų_metus',
	    'yy': 'metai_metų_metus'
	};
	function translateSeconds(number, withoutSuffix, key, isFuture) {
	    if (withoutSuffix) {
	        return 'kelios sekundės';
	    } else {
	        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
	    }
	}
	function translateSingular(number, withoutSuffix, key, isFuture) {
	    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
	}
	function special(number) {
	    return number % 10 === 0 || (number > 10 && number < 20);
	}
	function forms(key) {
	    return units[key].split('_');
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    if (number === 1) {
	        return result + translateSingular(number, withoutSuffix, key[0], isFuture);
	    } else if (withoutSuffix) {
	        return result + (special(number) ? forms(key)[1] : forms(key)[0]);
	    } else {
	        if (isFuture) {
	            return result + forms(key)[1];
	        } else {
	            return result + (special(number) ? forms(key)[1] : forms(key)[2]);
	        }
	    }
	}
	var lt = moment.defineLocale('lt', {
	    months : {
	        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
	        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
	        isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/
	    },
	    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
	    weekdays : {
	        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),
	        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),
	        isFormat: /dddd HH:mm/
	    },
	    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
	    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'YYYY [m.] MMMM D [d.]',
	        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
	        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
	        l : 'YYYY-MM-DD',
	        ll : 'YYYY [m.] MMMM D [d.]',
	        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
	        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
	    },
	    calendar : {
	        sameDay : '[Šiandien] LT',
	        nextDay : '[Rytoj] LT',
	        nextWeek : 'dddd LT',
	        lastDay : '[Vakar] LT',
	        lastWeek : '[Praėjusį] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'po %s',
	        past : 'prieš %s',
	        s : translateSeconds,
	        m : translateSingular,
	        mm : translate,
	        h : translateSingular,
	        hh : translate,
	        d : translateSingular,
	        dd : translate,
	        M : translateSingular,
	        MM : translate,
	        y : translateSingular,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-oji/,
	    ordinal : function (number) {
	        return number + '-oji';
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lt;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Latvian [lv]
	//! author : Kristaps Karlsons : https://github.com/skakri
	//! author : Jānis Elmeris : https://github.com/JanisE
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var units = {
	    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
	    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
	    'h': 'stundas_stundām_stunda_stundas'.split('_'),
	    'hh': 'stundas_stundām_stunda_stundas'.split('_'),
	    'd': 'dienas_dienām_diena_dienas'.split('_'),
	    'dd': 'dienas_dienām_diena_dienas'.split('_'),
	    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
	    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
	    'y': 'gada_gadiem_gads_gadi'.split('_'),
	    'yy': 'gada_gadiem_gads_gadi'.split('_')
	};
	/**
	 * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.
	 */
	function format(forms, number, withoutSuffix) {
	    if (withoutSuffix) {
	        // E.g. "21 minūte", "3 minūtes".
	        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];
	    } else {
	        // E.g. "21 minūtes" as in "pēc 21 minūtes".
	        // E.g. "3 minūtēm" as in "pēc 3 minūtēm".
	        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];
	    }
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    return number + ' ' + format(units[key], number, withoutSuffix);
	}
	function relativeTimeWithSingular(number, withoutSuffix, key) {
	    return format(units[key], number, withoutSuffix);
	}
	function relativeSeconds(number, withoutSuffix) {
	    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';
	}
	
	var lv = moment.defineLocale('lv', {
	    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),
	    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),
	    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY.',
	        LL : 'YYYY. [gada] D. MMMM',
	        LLL : 'YYYY. [gada] D. MMMM, HH:mm',
	        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
	    },
	    calendar : {
	        sameDay : '[Šodien pulksten] LT',
	        nextDay : '[Rīt pulksten] LT',
	        nextWeek : 'dddd [pulksten] LT',
	        lastDay : '[Vakar pulksten] LT',
	        lastWeek : '[Pagājušā] dddd [pulksten] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'pēc %s',
	        past : 'pirms %s',
	        s : relativeSeconds,
	        m : relativeTimeWithSingular,
	        mm : relativeTimeWithPlural,
	        h : relativeTimeWithSingular,
	        hh : relativeTimeWithPlural,
	        d : relativeTimeWithSingular,
	        dd : relativeTimeWithPlural,
	        M : relativeTimeWithSingular,
	        MM : relativeTimeWithPlural,
	        y : relativeTimeWithSingular,
	        yy : relativeTimeWithPlural
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Montenegrin [me]
	//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['jedan minut', 'jednog minuta'],
	        mm: ['minut', 'minuta', 'minuta'],
	        h: ['jedan sat', 'jednog sata'],
	        hh: ['sat', 'sata', 'sati'],
	        dd: ['dan', 'dana', 'dana'],
	        MM: ['mjesec', 'mjeseca', 'mjeseci'],
	        yy: ['godina', 'godine', 'godina']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var me = moment.defineLocale('me', {
	    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact : true,
	    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[danas u] LT',
	        nextDay: '[sjutra u] LT',
	
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[juče u] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[prošle] [nedjelje] [u] LT',
	                '[prošlog] [ponedjeljka] [u] LT',
	                '[prošlog] [utorka] [u] LT',
	                '[prošle] [srijede] [u] LT',
	                '[prošlog] [četvrtka] [u] LT',
	                '[prošlog] [petka] [u] LT',
	                '[prošle] [subote] [u] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'nekoliko sekundi',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'dan',
	        dd     : translator.translate,
	        M      : 'mjesec',
	        MM     : translator.translate,
	        y      : 'godinu',
	        yy     : translator.translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return me;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Maori [mi]
	//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var mi = moment.defineLocale('mi', {
	    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),
	    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),
	    monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,
	    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),
	    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
	    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY [i] HH:mm',
	        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'
	    },
	    calendar: {
	        sameDay: '[i teie mahana, i] LT',
	        nextDay: '[apopo i] LT',
	        nextWeek: 'dddd [i] LT',
	        lastDay: '[inanahi i] LT',
	        lastWeek: 'dddd [whakamutunga i] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'i roto i %s',
	        past: '%s i mua',
	        s: 'te hēkona ruarua',
	        m: 'he meneti',
	        mm: '%d meneti',
	        h: 'te haora',
	        hh: '%d haora',
	        d: 'he ra',
	        dd: '%d ra',
	        M: 'he marama',
	        MM: '%d marama',
	        y: 'he tau',
	        yy: '%d tau'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}º/,
	    ordinal: '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return mi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Macedonian [mk]
	//! author : Borislav Mickov : https://github.com/B0k0
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var mk = moment.defineLocale('mk', {
	    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),
	    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),
	    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),
	    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),
	    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'D.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay : '[Денес во] LT',
	        nextDay : '[Утре во] LT',
	        nextWeek : '[Во] dddd [во] LT',
	        lastDay : '[Вчера во] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 6:
	                    return '[Изминатата] dddd [во] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[Изминатиот] dddd [во] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'после %s',
	        past : 'пред %s',
	        s : 'неколку секунди',
	        m : 'минута',
	        mm : '%d минути',
	        h : 'час',
	        hh : '%d часа',
	        d : 'ден',
	        dd : '%d дена',
	        M : 'месец',
	        MM : '%d месеци',
	        y : 'година',
	        yy : '%d години'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
	    ordinal : function (number) {
	        var lastDigit = number % 10,
	            last2Digits = number % 100;
	        if (number === 0) {
	            return number + '-ев';
	        } else if (last2Digits === 0) {
	            return number + '-ен';
	        } else if (last2Digits > 10 && last2Digits < 20) {
	            return number + '-ти';
	        } else if (lastDigit === 1) {
	            return number + '-ви';
	        } else if (lastDigit === 2) {
	            return number + '-ри';
	        } else if (lastDigit === 7 || lastDigit === 8) {
	            return number + '-ми';
	        } else {
	            return number + '-ти';
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return mk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Malayalam [ml]
	//! author : Floyd Pink : https://github.com/floydpink
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ml = moment.defineLocale('ml', {
	    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),
	    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),
	    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),
	    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm -നു',
	        LTS : 'A h:mm:ss -നു',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm -നു',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
	    },
	    calendar : {
	        sameDay : '[ഇന്ന്] LT',
	        nextDay : '[നാളെ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ഇന്നലെ] LT',
	        lastWeek : '[കഴിഞ്ഞ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s കഴിഞ്ഞ്',
	        past : '%s മുൻപ്',
	        s : 'അൽപ നിമിഷങ്ങൾ',
	        m : 'ഒരു മിനിറ്റ്',
	        mm : '%d മിനിറ്റ്',
	        h : 'ഒരു മണിക്കൂർ',
	        hh : '%d മണിക്കൂർ',
	        d : 'ഒരു ദിവസം',
	        dd : '%d ദിവസം',
	        M : 'ഒരു മാസം',
	        MM : '%d മാസം',
	        y : 'ഒരു വർഷം',
	        yy : '%d വർഷം'
	    },
	    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'രാത്രി' && hour >= 4) ||
	                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||
	                meridiem === 'വൈകുന്നേരം') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'രാത്രി';
	        } else if (hour < 12) {
	            return 'രാവിലെ';
	        } else if (hour < 17) {
	            return 'ഉച്ച കഴിഞ്ഞ്';
	        } else if (hour < 20) {
	            return 'വൈകുന്നേരം';
	        } else {
	            return 'രാത്രി';
	        }
	    }
	});
	
	return ml;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Marathi [mr]
	//! author : Harshad Kale : https://github.com/kalehv
	//! author : Vivek Athalye : https://github.com/vnathalye
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	function relativeTimeMr(number, withoutSuffix, string, isFuture)
	{
	    var output = '';
	    if (withoutSuffix) {
	        switch (string) {
	            case 's': output = 'काही सेकंद'; break;
	            case 'm': output = 'एक मिनिट'; break;
	            case 'mm': output = '%d मिनिटे'; break;
	            case 'h': output = 'एक तास'; break;
	            case 'hh': output = '%d तास'; break;
	            case 'd': output = 'एक दिवस'; break;
	            case 'dd': output = '%d दिवस'; break;
	            case 'M': output = 'एक महिना'; break;
	            case 'MM': output = '%d महिने'; break;
	            case 'y': output = 'एक वर्ष'; break;
	            case 'yy': output = '%d वर्षे'; break;
	        }
	    }
	    else {
	        switch (string) {
	            case 's': output = 'काही सेकंदां'; break;
	            case 'm': output = 'एका मिनिटा'; break;
	            case 'mm': output = '%d मिनिटां'; break;
	            case 'h': output = 'एका तासा'; break;
	            case 'hh': output = '%d तासां'; break;
	            case 'd': output = 'एका दिवसा'; break;
	            case 'dd': output = '%d दिवसां'; break;
	            case 'M': output = 'एका महिन्या'; break;
	            case 'MM': output = '%d महिन्यां'; break;
	            case 'y': output = 'एका वर्षा'; break;
	            case 'yy': output = '%d वर्षां'; break;
	        }
	    }
	    return output.replace(/%d/i, number);
	}
	
	var mr = moment.defineLocale('mr', {
	    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),
	    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
	    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),
	    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm वाजता',
	        LTS : 'A h:mm:ss वाजता',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm वाजता',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[उद्या] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[काल] LT',
	        lastWeek: '[मागील] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future: '%sमध्ये',
	        past: '%sपूर्वी',
	        s: relativeTimeMr,
	        m: relativeTimeMr,
	        mm: relativeTimeMr,
	        h: relativeTimeMr,
	        hh: relativeTimeMr,
	        d: relativeTimeMr,
	        dd: relativeTimeMr,
	        M: relativeTimeMr,
	        MM: relativeTimeMr,
	        y: relativeTimeMr,
	        yy: relativeTimeMr
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'रात्री') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'सकाळी') {
	            return hour;
	        } else if (meridiem === 'दुपारी') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'सायंकाळी') {
	            return hour + 12;
	        }
	    },
	    meridiem: function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'रात्री';
	        } else if (hour < 10) {
	            return 'सकाळी';
	        } else if (hour < 17) {
	            return 'दुपारी';
	        } else if (hour < 20) {
	            return 'सायंकाळी';
	        } else {
	            return 'रात्री';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return mr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Malay [ms]
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ms = moment.defineLocale('ms', {
	    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
	    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
	    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
	    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|tengahari|petang|malam/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'tengahari') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'petang' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'tengahari';
	        } else if (hours < 19) {
	            return 'petang';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Esok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kelmarin pukul] LT',
	        lastWeek : 'dddd [lepas pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lepas',
	        s : 'beberapa saat',
	        m : 'seminit',
	        mm : '%d minit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ms;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Malay [ms-my]
	//! note : DEPRECATED, the correct one is [ms]
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var msMy = moment.defineLocale('ms-my', {
	    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
	    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
	    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
	    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|tengahari|petang|malam/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'tengahari') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'petang' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'tengahari';
	        } else if (hours < 19) {
	            return 'petang';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Esok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kelmarin pukul] LT',
	        lastWeek : 'dddd [lepas pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lepas',
	        s : 'beberapa saat',
	        m : 'seminit',
	        mm : '%d minit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return msMy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Burmese [my]
	//! author : Squar team, mysquar.com
	//! author : David Rossellat : https://github.com/gholadr
	//! author : Tin Aung Lin : https://github.com/thanyawzinmin
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '၁',
	    '2': '၂',
	    '3': '၃',
	    '4': '၄',
	    '5': '၅',
	    '6': '၆',
	    '7': '၇',
	    '8': '၈',
	    '9': '၉',
	    '0': '၀'
	};
	var numberMap = {
	    '၁': '1',
	    '၂': '2',
	    '၃': '3',
	    '၄': '4',
	    '၅': '5',
	    '၆': '6',
	    '၇': '7',
	    '၈': '8',
	    '၉': '9',
	    '၀': '0'
	};
	
	var my = moment.defineLocale('my', {
	    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),
	    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),
	    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),
	    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
	    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
	
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[ယနေ.] LT [မှာ]',
	        nextDay: '[မနက်ဖြန်] LT [မှာ]',
	        nextWeek: 'dddd LT [မှာ]',
	        lastDay: '[မနေ.က] LT [မှာ]',
	        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'လာမည့် %s မှာ',
	        past: 'လွန်ခဲ့သော %s က',
	        s: 'စက္ကန်.အနည်းငယ်',
	        m: 'တစ်မိနစ်',
	        mm: '%d မိနစ်',
	        h: 'တစ်နာရီ',
	        hh: '%d နာရီ',
	        d: 'တစ်ရက်',
	        dd: '%d ရက်',
	        M: 'တစ်လ',
	        MM: '%d လ',
	        y: 'တစ်နှစ်',
	        yy: '%d နှစ်'
	    },
	    preparse: function (string) {
	        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return my;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Norwegian Bokmål [nb]
	//! authors : Espen Hovlandsdal : https://github.com/rexxars
	//!           Sigurd Gartmann : https://github.com/sigurdga
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var nb = moment.defineLocale('nb', {
	    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
	    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),
	    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] HH:mm',
	        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[i dag kl.] LT',
	        nextDay: '[i morgen kl.] LT',
	        nextWeek: 'dddd [kl.] LT',
	        lastDay: '[i går kl.] LT',
	        lastWeek: '[forrige] dddd [kl.] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s siden',
	        s : 'noen sekunder',
	        m : 'ett minutt',
	        mm : '%d minutter',
	        h : 'en time',
	        hh : '%d timer',
	        d : 'en dag',
	        dd : '%d dager',
	        M : 'en måned',
	        MM : '%d måneder',
	        y : 'ett år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nb;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Nepalese [ne]
	//! author : suvash : https://github.com/suvash
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	var ne = moment.defineLocale('ne', {
	    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),
	    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),
	    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),
	    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'Aको h:mm बजे',
	        LTS : 'Aको h:mm:ss बजे',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, Aको h:mm बजे',
	        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'राति') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'बिहान') {
	            return hour;
	        } else if (meridiem === 'दिउँसो') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'साँझ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 3) {
	            return 'राति';
	        } else if (hour < 12) {
	            return 'बिहान';
	        } else if (hour < 16) {
	            return 'दिउँसो';
	        } else if (hour < 20) {
	            return 'साँझ';
	        } else {
	            return 'राति';
	        }
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[भोलि] LT',
	        nextWeek : '[आउँदो] dddd[,] LT',
	        lastDay : '[हिजो] LT',
	        lastWeek : '[गएको] dddd[,] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%sमा',
	        past : '%s अगाडि',
	        s : 'केही क्षण',
	        m : 'एक मिनेट',
	        mm : '%d मिनेट',
	        h : 'एक घण्टा',
	        hh : '%d घण्टा',
	        d : 'एक दिन',
	        dd : '%d दिन',
	        M : 'एक महिना',
	        MM : '%d महिना',
	        y : 'एक बर्ष',
	        yy : '%d बर्ष'
	    },
	    week : {
	        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.
	    }
	});
	
	return ne;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Dutch [nl]
	//! author : Joris Röling : https://github.com/jorisroling
	//! author : Jacob Middag : https://github.com/middagj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
	
	var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];
	var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
	
	var nl = moment.defineLocale('nl', {
	    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortWithDots;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	
	    monthsRegex: monthsRegex,
	    monthsShortRegex: monthsRegex,
	    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,
	    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
	
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
	    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
	    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[vandaag om] LT',
	        nextDay: '[morgen om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[gisteren om] LT',
	        lastWeek: '[afgelopen] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'over %s',
	        past : '%s geleden',
	        s : 'een paar seconden',
	        m : 'één minuut',
	        mm : '%d minuten',
	        h : 'één uur',
	        hh : '%d uur',
	        d : 'één dag',
	        dd : '%d dagen',
	        M : 'één maand',
	        MM : '%d maanden',
	        y : 'één jaar',
	        yy : '%d jaar'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Dutch (Belgium) [nl-be]
	//! author : Joris Röling : https://github.com/jorisroling
	//! author : Jacob Middag : https://github.com/middagj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
	
	var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];
	var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
	
	var nlBe = moment.defineLocale('nl-be', {
	    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortWithDots;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	
	    monthsRegex: monthsRegex,
	    monthsShortRegex: monthsRegex,
	    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,
	    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
	
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
	    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
	    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[vandaag om] LT',
	        nextDay: '[morgen om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[gisteren om] LT',
	        lastWeek: '[afgelopen] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'over %s',
	        past : '%s geleden',
	        s : 'een paar seconden',
	        m : 'één minuut',
	        mm : '%d minuten',
	        h : 'één uur',
	        hh : '%d uur',
	        d : 'één dag',
	        dd : '%d dagen',
	        M : 'één maand',
	        MM : '%d maanden',
	        y : 'één jaar',
	        yy : '%d jaar'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nlBe;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Nynorsk [nn]
	//! author : https://github.com/mechuwind
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var nn = moment.defineLocale('nn', {
	    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
	    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),
	    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),
	    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] H:mm',
	        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[I dag klokka] LT',
	        nextDay: '[I morgon klokka] LT',
	        nextWeek: 'dddd [klokka] LT',
	        lastDay: '[I går klokka] LT',
	        lastWeek: '[Føregåande] dddd [klokka] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s sidan',
	        s : 'nokre sekund',
	        m : 'eit minutt',
	        mm : '%d minutt',
	        h : 'ein time',
	        hh : '%d timar',
	        d : 'ein dag',
	        dd : '%d dagar',
	        M : 'ein månad',
	        MM : '%d månader',
	        y : 'eit år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Punjabi (India) [pa-in]
	//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '੧',
	    '2': '੨',
	    '3': '੩',
	    '4': '੪',
	    '5': '੫',
	    '6': '੬',
	    '7': '੭',
	    '8': '੮',
	    '9': '੯',
	    '0': '੦'
	};
	var numberMap = {
	    '੧': '1',
	    '੨': '2',
	    '੩': '3',
	    '੪': '4',
	    '੫': '5',
	    '੬': '6',
	    '੭': '7',
	    '੮': '8',
	    '੯': '9',
	    '੦': '0'
	};
	
	var paIn = moment.defineLocale('pa-in', {
	    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.
	    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),
	    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),
	    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),
	    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
	    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm ਵਜੇ',
	        LTS : 'A h:mm:ss ਵਜੇ',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'
	    },
	    calendar : {
	        sameDay : '[ਅਜ] LT',
	        nextDay : '[ਕਲ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ਕਲ] LT',
	        lastWeek : '[ਪਿਛਲੇ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ਵਿੱਚ',
	        past : '%s ਪਿਛਲੇ',
	        s : 'ਕੁਝ ਸਕਿੰਟ',
	        m : 'ਇਕ ਮਿੰਟ',
	        mm : '%d ਮਿੰਟ',
	        h : 'ਇੱਕ ਘੰਟਾ',
	        hh : '%d ਘੰਟੇ',
	        d : 'ਇੱਕ ਦਿਨ',
	        dd : '%d ਦਿਨ',
	        M : 'ਇੱਕ ਮਹੀਨਾ',
	        MM : '%d ਮਹੀਨੇ',
	        y : 'ਇੱਕ ਸਾਲ',
	        yy : '%d ਸਾਲ'
	    },
	    preparse: function (string) {
	        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists
	    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.
	    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ਰਾਤ') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ਸਵੇਰ') {
	            return hour;
	        } else if (meridiem === 'ਦੁਪਹਿਰ') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'ਸ਼ਾਮ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ਰਾਤ';
	        } else if (hour < 10) {
	            return 'ਸਵੇਰ';
	        } else if (hour < 17) {
	            return 'ਦੁਪਹਿਰ';
	        } else if (hour < 20) {
	            return 'ਸ਼ਾਮ';
	        } else {
	            return 'ਰਾਤ';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return paIn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Polish [pl]
	//! author : Rafal Hirsz : https://github.com/evoL
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');
	var monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');
	function plural(n) {
	    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);
	}
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'minuta' : 'minutę';
	        case 'mm':
	            return result + (plural(number) ? 'minuty' : 'minut');
	        case 'h':
	            return withoutSuffix  ? 'godzina'  : 'godzinę';
	        case 'hh':
	            return result + (plural(number) ? 'godziny' : 'godzin');
	        case 'MM':
	            return result + (plural(number) ? 'miesiące' : 'miesięcy');
	        case 'yy':
	            return result + (plural(number) ? 'lata' : 'lat');
	    }
	}
	
	var pl = moment.defineLocale('pl', {
	    months : function (momentToFormat, format) {
	        if (!momentToFormat) {
	            return monthsNominative;
	        } else if (format === '') {
	            // Hack: if format empty we know this is used to generate
	            // RegExp by moment. Give then back both valid forms of months
	            // in RegExp ready format.
	            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';
	        } else if (/D MMMM/.test(format)) {
	            return monthsSubjective[momentToFormat.month()];
	        } else {
	            return monthsNominative[momentToFormat.month()];
	        }
	    },
	    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),
	    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),
	    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),
	    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Dziś o] LT',
	        nextDay: '[Jutro o] LT',
	        nextWeek: '[W] dddd [o] LT',
	        lastDay: '[Wczoraj o] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[W zeszłą niedzielę o] LT';
	                case 3:
	                    return '[W zeszłą środę o] LT';
	                case 6:
	                    return '[W zeszłą sobotę o] LT';
	                default:
	                    return '[W zeszły] dddd [o] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : '%s temu',
	        s : 'kilka sekund',
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : '1 dzień',
	        dd : '%d dni',
	        M : 'miesiąc',
	        MM : translate,
	        y : 'rok',
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return pl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Portuguese [pt]
	//! author : Jefferson : https://github.com/jalex79
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var pt = moment.defineLocale('pt', {
	    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
	    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY HH:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hoje às] LT',
	        nextDay: '[Amanhã às] LT',
	        nextWeek: 'dddd [às] LT',
	        lastDay: '[Ontem às] LT',
	        lastWeek: function () {
	            return (this.day() === 0 || this.day() === 6) ?
	                '[Último] dddd [às] LT' : // Saturday + Sunday
	                '[Última] dddd [às] LT'; // Monday - Friday
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'em %s',
	        past : 'há %s',
	        s : 'segundos',
	        m : 'um minuto',
	        mm : '%d minutos',
	        h : 'uma hora',
	        hh : '%d horas',
	        d : 'um dia',
	        dd : '%d dias',
	        M : 'um mês',
	        MM : '%d meses',
	        y : 'um ano',
	        yy : '%d anos'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return pt;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Portuguese (Brazil) [pt-br]
	//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ptBr = moment.defineLocale('pt-br', {
	    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
	    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hoje às] LT',
	        nextDay: '[Amanhã às] LT',
	        nextWeek: 'dddd [às] LT',
	        lastDay: '[Ontem às] LT',
	        lastWeek: function () {
	            return (this.day() === 0 || this.day() === 6) ?
	                '[Último] dddd [às] LT' : // Saturday + Sunday
	                '[Última] dddd [às] LT'; // Monday - Friday
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'em %s',
	        past : '%s atrás',
	        s : 'poucos segundos',
	        m : 'um minuto',
	        mm : '%d minutos',
	        h : 'uma hora',
	        hh : '%d horas',
	        d : 'um dia',
	        dd : '%d dias',
	        M : 'um mês',
	        MM : '%d meses',
	        y : 'um ano',
	        yy : '%d anos'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}º/,
	    ordinal : '%dº'
	});
	
	return ptBr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Romanian [ro]
	//! author : Vlad Gurdiga : https://github.com/gurdiga
	//! author : Valentin Agachi : https://github.com/avaly
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	            'mm': 'minute',
	            'hh': 'ore',
	            'dd': 'zile',
	            'MM': 'luni',
	            'yy': 'ani'
	        },
	        separator = ' ';
	    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
	        separator = ' de ';
	    }
	    return number + separator + format[key];
	}
	
	var ro = moment.defineLocale('ro', {
	    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),
	    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),
	    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),
	    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay: '[azi la] LT',
	        nextDay: '[mâine la] LT',
	        nextWeek: 'dddd [la] LT',
	        lastDay: '[ieri la] LT',
	        lastWeek: '[fosta] dddd [la] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'peste %s',
	        past : '%s în urmă',
	        s : 'câteva secunde',
	        m : 'un minut',
	        mm : relativeTimeWithPlural,
	        h : 'o oră',
	        hh : relativeTimeWithPlural,
	        d : 'o zi',
	        dd : relativeTimeWithPlural,
	        M : 'o lună',
	        MM : relativeTimeWithPlural,
	        y : 'un an',
	        yy : relativeTimeWithPlural
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ro;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Russian [ru]
	//! author : Viktorminator : https://github.com/Viktorminator
	//! Author : Menelion Elensúle : https://github.com/Oire
	//! author : Коренберг Марк : https://github.com/socketpair
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
	        'hh': 'час_часа_часов',
	        'dd': 'день_дня_дней',
	        'MM': 'месяц_месяца_месяцев',
	        'yy': 'год_года_лет'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'минута' : 'минуту';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];
	
	// http://new.gramota.ru/spravka/rules/139-prop : § 103
	// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637
	// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753
	var ru = moment.defineLocale('ru', {
	    months : {
	        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),
	        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')
	    },
	    monthsShort : {
	        // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ?
	        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),
	        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')
	    },
	    weekdays : {
	        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
	        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),
	        isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/
	    },
	    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
	    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки
	    monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
	
	    // копия предыдущего
	    monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
	
	    // полные названия с падежами
	    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,
	
	    // Выражение, которое соотвествует только сокращённым формам
	    monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY г.',
	        LLL : 'D MMMM YYYY г., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY г., HH:mm'
	    },
	    calendar : {
	        sameDay: '[Сегодня в] LT',
	        nextDay: '[Завтра в] LT',
	        lastDay: '[Вчера в] LT',
	        nextWeek: function (now) {
	            if (now.week() !== this.week()) {
	                switch (this.day()) {
	                    case 0:
	                        return '[В следующее] dddd [в] LT';
	                    case 1:
	                    case 2:
	                    case 4:
	                        return '[В следующий] dddd [в] LT';
	                    case 3:
	                    case 5:
	                    case 6:
	                        return '[В следующую] dddd [в] LT';
	                }
	            } else {
	                if (this.day() === 2) {
	                    return '[Во] dddd [в] LT';
	                } else {
	                    return '[В] dddd [в] LT';
	                }
	            }
	        },
	        lastWeek: function (now) {
	            if (now.week() !== this.week()) {
	                switch (this.day()) {
	                    case 0:
	                        return '[В прошлое] dddd [в] LT';
	                    case 1:
	                    case 2:
	                    case 4:
	                        return '[В прошлый] dddd [в] LT';
	                    case 3:
	                    case 5:
	                    case 6:
	                        return '[В прошлую] dddd [в] LT';
	                }
	            } else {
	                if (this.day() === 2) {
	                    return '[Во] dddd [в] LT';
	                } else {
	                    return '[В] dddd [в] LT';
	                }
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'через %s',
	        past : '%s назад',
	        s : 'несколько секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : 'час',
	        hh : relativeTimeWithPlural,
	        d : 'день',
	        dd : relativeTimeWithPlural,
	        M : 'месяц',
	        MM : relativeTimeWithPlural,
	        y : 'год',
	        yy : relativeTimeWithPlural
	    },
	    meridiemParse: /ночи|утра|дня|вечера/i,
	    isPM : function (input) {
	        return /^(дня|вечера)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночи';
	        } else if (hour < 12) {
	            return 'утра';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечера';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	                return number + '-й';
	            case 'D':
	                return number + '-го';
	            case 'w':
	            case 'W':
	                return number + '-я';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ru;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Sindhi [sd]
	//! author : Narain Sagar : https://github.com/narainsagar
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'جنوري',
	    'فيبروري',
	    'مارچ',
	    'اپريل',
	    'مئي',
	    'جون',
	    'جولاءِ',
	    'آگسٽ',
	    'سيپٽمبر',
	    'آڪٽوبر',
	    'نومبر',
	    'ڊسمبر'
	];
	var days = [
	    'آچر',
	    'سومر',
	    'اڱارو',
	    'اربع',
	    'خميس',
	    'جمع',
	    'ڇنڇر'
	];
	
	var sd = moment.defineLocale('sd', {
	    months : months,
	    monthsShort : months,
	    weekdays : days,
	    weekdaysShort : days,
	    weekdaysMin : days,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd، D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /صبح|شام/,
	    isPM : function (input) {
	        return 'شام' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'صبح';
	        }
	        return 'شام';
	    },
	    calendar : {
	        sameDay : '[اڄ] LT',
	        nextDay : '[سڀاڻي] LT',
	        nextWeek : 'dddd [اڳين هفتي تي] LT',
	        lastDay : '[ڪالهه] LT',
	        lastWeek : '[گزريل هفتي] dddd [تي] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s پوء',
	        past : '%s اڳ',
	        s : 'چند سيڪنڊ',
	        m : 'هڪ منٽ',
	        mm : '%d منٽ',
	        h : 'هڪ ڪلاڪ',
	        hh : '%d ڪلاڪ',
	        d : 'هڪ ڏينهن',
	        dd : '%d ڏينهن',
	        M : 'هڪ مهينو',
	        MM : '%d مهينا',
	        y : 'هڪ سال',
	        yy : '%d سال'
	    },
	    preparse: function (string) {
	        return string.replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/,/g, '،');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sd;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Northern Sami [se]
	//! authors : Bård Rolstad Henriksen : https://github.com/karamell
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var se = moment.defineLocale('se', {
	    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),
	    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),
	    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),
	    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),
	    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'MMMM D. [b.] YYYY',
	        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',
	        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[otne ti] LT',
	        nextDay: '[ihttin ti] LT',
	        nextWeek: 'dddd [ti] LT',
	        lastDay: '[ikte ti] LT',
	        lastWeek: '[ovddit] dddd [ti] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s geažes',
	        past : 'maŋit %s',
	        s : 'moadde sekunddat',
	        m : 'okta minuhta',
	        mm : '%d minuhtat',
	        h : 'okta diimmu',
	        hh : '%d diimmut',
	        d : 'okta beaivi',
	        dd : '%d beaivvit',
	        M : 'okta mánnu',
	        MM : '%d mánut',
	        y : 'okta jahki',
	        yy : '%d jagit'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return se;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Sinhalese [si]
	//! author : Sampath Sitinamaluwa : https://github.com/sampathsris
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	/*jshint -W100*/
	var si = moment.defineLocale('si', {
	    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),
	    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),
	    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),
	    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),
	    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'a h:mm',
	        LTS : 'a h:mm:ss',
	        L : 'YYYY/MM/DD',
	        LL : 'YYYY MMMM D',
	        LLL : 'YYYY MMMM D, a h:mm',
	        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
	    },
	    calendar : {
	        sameDay : '[අද] LT[ට]',
	        nextDay : '[හෙට] LT[ට]',
	        nextWeek : 'dddd LT[ට]',
	        lastDay : '[ඊයේ] LT[ට]',
	        lastWeek : '[පසුගිය] dddd LT[ට]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%sකින්',
	        past : '%sකට පෙර',
	        s : 'තත්පර කිහිපය',
	        m : 'මිනිත්තුව',
	        mm : 'මිනිත්තු %d',
	        h : 'පැය',
	        hh : 'පැය %d',
	        d : 'දිනය',
	        dd : 'දින %d',
	        M : 'මාසය',
	        MM : 'මාස %d',
	        y : 'වසර',
	        yy : 'වසර %d'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2} වැනි/,
	    ordinal : function (number) {
	        return number + ' වැනි';
	    },
	    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,
	    isPM : function (input) {
	        return input === 'ප.ව.' || input === 'පස් වරු';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'ප.ව.' : 'පස් වරු';
	        } else {
	            return isLower ? 'පෙ.ව.' : 'පෙර වරු';
	        }
	    }
	});
	
	return si;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Slovak [sk]
	//! author : Martin Minka : https://github.com/k2s
	//! based on work of petrbela : https://github.com/petrbela
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');
	var monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');
	function plural(n) {
	    return (n > 1) && (n < 5);
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':  // a few seconds / in a few seconds / a few seconds ago
	            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';
	        case 'm':  // a minute / in a minute / a minute ago
	            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');
	        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'minúty' : 'minút');
	            } else {
	                return result + 'minútami';
	            }
	            break;
	        case 'h':  // an hour / in an hour / an hour ago
	            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
	        case 'hh': // 9 hours / in 9 hours / 9 hours ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'hodiny' : 'hodín');
	            } else {
	                return result + 'hodinami';
	            }
	            break;
	        case 'd':  // a day / in a day / a day ago
	            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';
	        case 'dd': // 9 days / in 9 days / 9 days ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'dni' : 'dní');
	            } else {
	                return result + 'dňami';
	            }
	            break;
	        case 'M':  // a month / in a month / a month ago
	            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';
	        case 'MM': // 9 months / in 9 months / 9 months ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'mesiace' : 'mesiacov');
	            } else {
	                return result + 'mesiacmi';
	            }
	            break;
	        case 'y':  // a year / in a year / a year ago
	            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';
	        case 'yy': // 9 years / in 9 years / 9 years ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'roky' : 'rokov');
	            } else {
	                return result + 'rokmi';
	            }
	            break;
	    }
	}
	
	var sk = moment.defineLocale('sk', {
	    months : months,
	    monthsShort : monthsShort,
	    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),
	    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),
	    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
	    longDateFormat : {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay: '[dnes o] LT',
	        nextDay: '[zajtra o] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v nedeľu o] LT';
	                case 1:
	                case 2:
	                    return '[v] dddd [o] LT';
	                case 3:
	                    return '[v stredu o] LT';
	                case 4:
	                    return '[vo štvrtok o] LT';
	                case 5:
	                    return '[v piatok o] LT';
	                case 6:
	                    return '[v sobotu o] LT';
	            }
	        },
	        lastDay: '[včera o] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[minulú nedeľu o] LT';
	                case 1:
	                case 2:
	                    return '[minulý] dddd [o] LT';
	                case 3:
	                    return '[minulú stredu o] LT';
	                case 4:
	                case 5:
	                    return '[minulý] dddd [o] LT';
	                case 6:
	                    return '[minulú sobotu o] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : 'pred %s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Slovenian [sl]
	//! author : Robert Sedovšek : https://github.com/sedovsek
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':
	            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';
	        case 'm':
	            return withoutSuffix ? 'ena minuta' : 'eno minuto';
	        case 'mm':
	            if (number === 1) {
	                result += withoutSuffix ? 'minuta' : 'minuto';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'minute' : 'minutami';
	            } else {
	                result += withoutSuffix || isFuture ? 'minut' : 'minutami';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'ena ura' : 'eno uro';
	        case 'hh':
	            if (number === 1) {
	                result += withoutSuffix ? 'ura' : 'uro';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'uri' : 'urama';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'ure' : 'urami';
	            } else {
	                result += withoutSuffix || isFuture ? 'ur' : 'urami';
	            }
	            return result;
	        case 'd':
	            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';
	        case 'dd':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'dan' : 'dnem';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';
	            } else {
	                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';
	            }
	            return result;
	        case 'M':
	            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';
	        case 'MM':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';
	            } else {
	                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';
	            }
	            return result;
	        case 'y':
	            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';
	        case 'yy':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'leto' : 'letom';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'leti' : 'letoma';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'leta' : 'leti';
	            } else {
	                result += withoutSuffix || isFuture ? 'let' : 'leti';
	            }
	            return result;
	    }
	}
	
	var sl = moment.defineLocale('sl', {
	    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),
	    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),
	    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danes ob] LT',
	        nextDay  : '[jutri ob] LT',
	
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v] [nedeljo] [ob] LT';
	                case 3:
	                    return '[v] [sredo] [ob] LT';
	                case 6:
	                    return '[v] [soboto] [ob] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[v] dddd [ob] LT';
	            }
	        },
	        lastDay  : '[včeraj ob] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[prejšnjo] [nedeljo] [ob] LT';
	                case 3:
	                    return '[prejšnjo] [sredo] [ob] LT';
	                case 6:
	                    return '[prejšnjo] [soboto] [ob] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prejšnji] dddd [ob] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'čez %s',
	        past   : 'pred %s',
	        s      : processRelativeTime,
	        m      : processRelativeTime,
	        mm     : processRelativeTime,
	        h      : processRelativeTime,
	        hh     : processRelativeTime,
	        d      : processRelativeTime,
	        dd     : processRelativeTime,
	        M      : processRelativeTime,
	        MM     : processRelativeTime,
	        y      : processRelativeTime,
	        yy     : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Albanian [sq]
	//! author : Flakërim Ismani : https://github.com/flakerimi
	//! author : Menelion Elensúle : https://github.com/Oire
	//! author : Oerd Cukalla : https://github.com/oerd
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sq = moment.defineLocale('sq', {
	    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),
	    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),
	    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),
	    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),
	    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),
	    weekdaysParseExact : true,
	    meridiemParse: /PD|MD/,
	    isPM: function (input) {
	        return input.charAt(0) === 'M';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        return hours < 12 ? 'PD' : 'MD';
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Sot në] LT',
	        nextDay : '[Nesër në] LT',
	        nextWeek : 'dddd [në] LT',
	        lastDay : '[Dje në] LT',
	        lastWeek : 'dddd [e kaluar në] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'në %s',
	        past : '%s më parë',
	        s : 'disa sekonda',
	        m : 'një minutë',
	        mm : '%d minuta',
	        h : 'një orë',
	        hh : '%d orë',
	        d : 'një ditë',
	        dd : '%d ditë',
	        M : 'një muaj',
	        MM : '%d muaj',
	        y : 'një vit',
	        yy : '%d vite'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sq;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Serbian [sr]
	//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['jedan minut', 'jedne minute'],
	        mm: ['minut', 'minute', 'minuta'],
	        h: ['jedan sat', 'jednog sata'],
	        hh: ['sat', 'sata', 'sati'],
	        dd: ['dan', 'dana', 'dana'],
	        MM: ['mesec', 'meseca', 'meseci'],
	        yy: ['godina', 'godine', 'godina']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var sr = moment.defineLocale('sr', {
	    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),
	    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[danas u] LT',
	        nextDay: '[sutra u] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedelju] [u] LT';
	                case 3:
	                    return '[u] [sredu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[juče u] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[prošle] [nedelje] [u] LT',
	                '[prošlog] [ponedeljka] [u] LT',
	                '[prošlog] [utorka] [u] LT',
	                '[prošle] [srede] [u] LT',
	                '[prošlog] [četvrtka] [u] LT',
	                '[prošlog] [petka] [u] LT',
	                '[prošle] [subote] [u] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'pre %s',
	        s      : 'nekoliko sekundi',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'dan',
	        dd     : translator.translate,
	        M      : 'mesec',
	        MM     : translator.translate,
	        y      : 'godinu',
	        yy     : translator.translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Serbian Cyrillic [sr-cyrl]
	//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['један минут', 'једне минуте'],
	        mm: ['минут', 'минуте', 'минута'],
	        h: ['један сат', 'једног сата'],
	        hh: ['сат', 'сата', 'сати'],
	        dd: ['дан', 'дана', 'дана'],
	        MM: ['месец', 'месеца', 'месеци'],
	        yy: ['година', 'године', 'година']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var srCyrl = moment.defineLocale('sr-cyrl', {
	    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),
	    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),
	    monthsParseExact: true,
	    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),
	    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),
	    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[данас у] LT',
	        nextDay: '[сутра у] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[у] [недељу] [у] LT';
	                case 3:
	                    return '[у] [среду] [у] LT';
	                case 6:
	                    return '[у] [суботу] [у] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[у] dddd [у] LT';
	            }
	        },
	        lastDay  : '[јуче у] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[прошле] [недеље] [у] LT',
	                '[прошлог] [понедељка] [у] LT',
	                '[прошлог] [уторка] [у] LT',
	                '[прошле] [среде] [у] LT',
	                '[прошлог] [четвртка] [у] LT',
	                '[прошлог] [петка] [у] LT',
	                '[прошле] [суботе] [у] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'за %s',
	        past   : 'пре %s',
	        s      : 'неколико секунди',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'дан',
	        dd     : translator.translate,
	        M      : 'месец',
	        MM     : translator.translate,
	        y      : 'годину',
	        yy     : translator.translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return srCyrl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : siSwati [ss]
	//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var ss = moment.defineLocale('ss', {
	    months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'),
	    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),
	    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),
	    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),
	    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Namuhla nga] LT',
	        nextDay : '[Kusasa nga] LT',
	        nextWeek : 'dddd [nga] LT',
	        lastDay : '[Itolo nga] LT',
	        lastWeek : 'dddd [leliphelile] [nga] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'nga %s',
	        past : 'wenteka nga %s',
	        s : 'emizuzwana lomcane',
	        m : 'umzuzu',
	        mm : '%d emizuzu',
	        h : 'lihora',
	        hh : '%d emahora',
	        d : 'lilanga',
	        dd : '%d emalanga',
	        M : 'inyanga',
	        MM : '%d tinyanga',
	        y : 'umnyaka',
	        yy : '%d iminyaka'
	    },
	    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'ekuseni';
	        } else if (hours < 15) {
	            return 'emini';
	        } else if (hours < 19) {
	            return 'entsambama';
	        } else {
	            return 'ebusuku';
	        }
	    },
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ekuseni') {
	            return hour;
	        } else if (meridiem === 'emini') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {
	            if (hour === 0) {
	                return 0;
	            }
	            return hour + 12;
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}/,
	    ordinal : '%d',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ss;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Swedish [sv]
	//! author : Jens Alm : https://github.com/ulmus
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sv = moment.defineLocale('sv', {
	    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),
	    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),
	    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [kl.] HH:mm',
	        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Idag] LT',
	        nextDay: '[Imorgon] LT',
	        lastDay: '[Igår] LT',
	        nextWeek: '[På] dddd LT',
	        lastWeek: '[I] dddd[s] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : 'för %s sedan',
	        s : 'några sekunder',
	        m : 'en minut',
	        mm : '%d minuter',
	        h : 'en timme',
	        hh : '%d timmar',
	        d : 'en dag',
	        dd : '%d dagar',
	        M : 'en månad',
	        MM : '%d månader',
	        y : 'ett år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(e|a)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'e' :
	            (b === 1) ? 'a' :
	            (b === 2) ? 'a' :
	            (b === 3) ? 'e' : 'e';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Swahili [sw]
	//! author : Fahad Kassim : https://github.com/fadsel
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sw = moment.defineLocale('sw', {
	    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),
	    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),
	    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[leo saa] LT',
	        nextDay : '[kesho saa] LT',
	        nextWeek : '[wiki ijayo] dddd [saat] LT',
	        lastDay : '[jana] LT',
	        lastWeek : '[wiki iliyopita] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s baadaye',
	        past : 'tokea %s',
	        s : 'hivi punde',
	        m : 'dakika moja',
	        mm : 'dakika %d',
	        h : 'saa limoja',
	        hh : 'masaa %d',
	        d : 'siku moja',
	        dd : 'masiku %d',
	        M : 'mwezi mmoja',
	        MM : 'miezi %d',
	        y : 'mwaka mmoja',
	        yy : 'miaka %d'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sw;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tamil [ta]
	//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '௧',
	    '2': '௨',
	    '3': '௩',
	    '4': '௪',
	    '5': '௫',
	    '6': '௬',
	    '7': '௭',
	    '8': '௮',
	    '9': '௯',
	    '0': '௦'
	};
	var numberMap = {
	    '௧': '1',
	    '௨': '2',
	    '௩': '3',
	    '௪': '4',
	    '௫': '5',
	    '௬': '6',
	    '௭': '7',
	    '௮': '8',
	    '௯': '9',
	    '௦': '0'
	};
	
	var ta = moment.defineLocale('ta', {
	    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
	    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
	    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),
	    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),
	    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, HH:mm',
	        LLLL : 'dddd, D MMMM YYYY, HH:mm'
	    },
	    calendar : {
	        sameDay : '[இன்று] LT',
	        nextDay : '[நாளை] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[நேற்று] LT',
	        lastWeek : '[கடந்த வாரம்] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s இல்',
	        past : '%s முன்',
	        s : 'ஒரு சில விநாடிகள்',
	        m : 'ஒரு நிமிடம்',
	        mm : '%d நிமிடங்கள்',
	        h : 'ஒரு மணி நேரம்',
	        hh : '%d மணி நேரம்',
	        d : 'ஒரு நாள்',
	        dd : '%d நாட்கள்',
	        M : 'ஒரு மாதம்',
	        MM : '%d மாதங்கள்',
	        y : 'ஒரு வருடம்',
	        yy : '%d ஆண்டுகள்'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}வது/,
	    ordinal : function (number) {
	        return number + 'வது';
	    },
	    preparse: function (string) {
	        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // refer http://ta.wikipedia.org/s/1er1
	    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 2) {
	            return ' யாமம்';
	        } else if (hour < 6) {
	            return ' வைகறை';  // வைகறை
	        } else if (hour < 10) {
	            return ' காலை'; // காலை
	        } else if (hour < 14) {
	            return ' நண்பகல்'; // நண்பகல்
	        } else if (hour < 18) {
	            return ' எற்பாடு'; // எற்பாடு
	        } else if (hour < 22) {
	            return ' மாலை'; // மாலை
	        } else {
	            return ' யாமம்';
	        }
	    },
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'யாமம்') {
	            return hour < 2 ? hour : hour + 12;
	        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {
	            return hour;
	        } else if (meridiem === 'நண்பகல்') {
	            return hour >= 10 ? hour : hour + 12;
	        } else {
	            return hour + 12;
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return ta;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Telugu [te]
	//! author : Krishna Chaitanya Thota : https://github.com/kcthota
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var te = moment.defineLocale('te', {
	    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),
	    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),
	    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),
	    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[నేడు] LT',
	        nextDay : '[రేపు] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[నిన్న] LT',
	        lastWeek : '[గత] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s లో',
	        past : '%s క్రితం',
	        s : 'కొన్ని క్షణాలు',
	        m : 'ఒక నిమిషం',
	        mm : '%d నిమిషాలు',
	        h : 'ఒక గంట',
	        hh : '%d గంటలు',
	        d : 'ఒక రోజు',
	        dd : '%d రోజులు',
	        M : 'ఒక నెల',
	        MM : '%d నెలలు',
	        y : 'ఒక సంవత్సరం',
	        yy : '%d సంవత్సరాలు'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}వ/,
	    ordinal : '%dవ',
	    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'రాత్రి') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ఉదయం') {
	            return hour;
	        } else if (meridiem === 'మధ్యాహ్నం') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'సాయంత్రం') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'రాత్రి';
	        } else if (hour < 10) {
	            return 'ఉదయం';
	        } else if (hour < 17) {
	            return 'మధ్యాహ్నం';
	        } else if (hour < 20) {
	            return 'సాయంత్రం';
	        } else {
	            return 'రాత్రి';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return te;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tetun Dili (East Timor) [tet]
	//! author : Joshua Brooks : https://github.com/joshbrooks
	//! author : Onorio De J. Afonso : https://github.com/marobo
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tet = moment.defineLocale('tet', {
	    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),
	    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Ohin iha] LT',
	        nextDay: '[Aban iha] LT',
	        nextWeek: 'dddd [iha] LT',
	        lastDay: '[Horiseik iha] LT',
	        lastWeek: 'dddd [semana kotuk] [iha] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'iha %s',
	        past : '%s liuba',
	        s : 'minutu balun',
	        m : 'minutu ida',
	        mm : 'minutus %d',
	        h : 'horas ida',
	        hh : 'horas %d',
	        d : 'loron ida',
	        dd : 'loron %d',
	        M : 'fulan ida',
	        MM : 'fulan %d',
	        y : 'tinan ida',
	        yy : 'tinan %d'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tet;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Thai [th]
	//! author : Kridsada Thanabulpong : https://github.com/sirn
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var th = moment.defineLocale('th', {
	    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),
	    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),
	    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference
	    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY เวลา H:mm',
	        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'
	    },
	    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
	    isPM: function (input) {
	        return input === 'หลังเที่ยง';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ก่อนเที่ยง';
	        } else {
	            return 'หลังเที่ยง';
	        }
	    },
	    calendar : {
	        sameDay : '[วันนี้ เวลา] LT',
	        nextDay : '[พรุ่งนี้ เวลา] LT',
	        nextWeek : 'dddd[หน้า เวลา] LT',
	        lastDay : '[เมื่อวานนี้ เวลา] LT',
	        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'อีก %s',
	        past : '%sที่แล้ว',
	        s : 'ไม่กี่วินาที',
	        m : '1 นาที',
	        mm : '%d นาที',
	        h : '1 ชั่วโมง',
	        hh : '%d ชั่วโมง',
	        d : '1 วัน',
	        dd : '%d วัน',
	        M : '1 เดือน',
	        MM : '%d เดือน',
	        y : '1 ปี',
	        yy : '%d ปี'
	    }
	});
	
	return th;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tagalog (Philippines) [tl-ph]
	//! author : Dan Hagman : https://github.com/hagmandan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tlPh = moment.defineLocale('tl-ph', {
	    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),
	    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),
	    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),
	    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),
	    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'MM/D/YYYY',
	        LL : 'MMMM D, YYYY',
	        LLL : 'MMMM D, YYYY HH:mm',
	        LLLL : 'dddd, MMMM DD, YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: 'LT [ngayong araw]',
	        nextDay: '[Bukas ng] LT',
	        nextWeek: 'LT [sa susunod na] dddd',
	        lastDay: 'LT [kahapon]',
	        lastWeek: 'LT [noong nakaraang] dddd',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'sa loob ng %s',
	        past : '%s ang nakalipas',
	        s : 'ilang segundo',
	        m : 'isang minuto',
	        mm : '%d minuto',
	        h : 'isang oras',
	        hh : '%d oras',
	        d : 'isang araw',
	        dd : '%d araw',
	        M : 'isang buwan',
	        MM : '%d buwan',
	        y : 'isang taon',
	        yy : '%d taon'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}/,
	    ordinal : function (number) {
	        return number;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tlPh;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Klingon [tlh]
	//! author : Dominika Kruk : https://github.com/amaranthrose
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');
	
	function translateFuture(output) {
	    var time = output;
	    time = (output.indexOf('jaj') !== -1) ?
	    time.slice(0, -3) + 'leS' :
	    (output.indexOf('jar') !== -1) ?
	    time.slice(0, -3) + 'waQ' :
	    (output.indexOf('DIS') !== -1) ?
	    time.slice(0, -3) + 'nem' :
	    time + ' pIq';
	    return time;
	}
	
	function translatePast(output) {
	    var time = output;
	    time = (output.indexOf('jaj') !== -1) ?
	    time.slice(0, -3) + 'Hu’' :
	    (output.indexOf('jar') !== -1) ?
	    time.slice(0, -3) + 'wen' :
	    (output.indexOf('DIS') !== -1) ?
	    time.slice(0, -3) + 'ben' :
	    time + ' ret';
	    return time;
	}
	
	function translate(number, withoutSuffix, string, isFuture) {
	    var numberNoun = numberAsNoun(number);
	    switch (string) {
	        case 'mm':
	            return numberNoun + ' tup';
	        case 'hh':
	            return numberNoun + ' rep';
	        case 'dd':
	            return numberNoun + ' jaj';
	        case 'MM':
	            return numberNoun + ' jar';
	        case 'yy':
	            return numberNoun + ' DIS';
	    }
	}
	
	function numberAsNoun(number) {
	    var hundred = Math.floor((number % 1000) / 100),
	    ten = Math.floor((number % 100) / 10),
	    one = number % 10,
	    word = '';
	    if (hundred > 0) {
	        word += numbersNouns[hundred] + 'vatlh';
	    }
	    if (ten > 0) {
	        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';
	    }
	    if (one > 0) {
	        word += ((word !== '') ? ' ' : '') + numbersNouns[one];
	    }
	    return (word === '') ? 'pagh' : word;
	}
	
	var tlh = moment.defineLocale('tlh', {
	    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),
	    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[DaHjaj] LT',
	        nextDay: '[wa’leS] LT',
	        nextWeek: 'LLL',
	        lastDay: '[wa’Hu’] LT',
	        lastWeek: 'LLL',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : translateFuture,
	        past : translatePast,
	        s : 'puS lup',
	        m : 'wa’ tup',
	        mm : translate,
	        h : 'wa’ rep',
	        hh : translate,
	        d : 'wa’ jaj',
	        dd : translate,
	        M : 'wa’ jar',
	        MM : translate,
	        y : 'wa’ DIS',
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tlh;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Turkish [tr]
	//! authors : Erhan Gundogan : https://github.com/erhangundogan,
	//!           Burak Yiğit Kaya: https://github.com/BYK
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    1: '\'inci',
	    5: '\'inci',
	    8: '\'inci',
	    70: '\'inci',
	    80: '\'inci',
	    2: '\'nci',
	    7: '\'nci',
	    20: '\'nci',
	    50: '\'nci',
	    3: '\'üncü',
	    4: '\'üncü',
	    100: '\'üncü',
	    6: '\'ncı',
	    9: '\'uncu',
	    10: '\'uncu',
	    30: '\'uncu',
	    60: '\'ıncı',
	    90: '\'ıncı'
	};
	
	var tr = moment.defineLocale('tr', {
	    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),
	    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
	    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),
	    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
	    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[bugün saat] LT',
	        nextDay : '[yarın saat] LT',
	        nextWeek : '[haftaya] dddd [saat] LT',
	        lastDay : '[dün] LT',
	        lastWeek : '[geçen hafta] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s sonra',
	        past : '%s önce',
	        s : 'birkaç saniye',
	        m : 'bir dakika',
	        mm : '%d dakika',
	        h : 'bir saat',
	        hh : '%d saat',
	        d : 'bir gün',
	        dd : '%d gün',
	        M : 'bir ay',
	        MM : '%d ay',
	        y : 'bir yıl',
	        yy : '%d yıl'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,
	    ordinal : function (number) {
	        if (number === 0) {  // special case for zero
	            return number + '\'ıncı';
	        }
	        var a = number % 10,
	            b = number % 100 - a,
	            c = number >= 100 ? 100 : null;
	        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Talossan [tzl]
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v
	//! author : Iustì Canun
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.
	// This is currently too difficult (maybe even impossible) to add.
	var tzl = moment.defineLocale('tzl', {
	    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
	    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
	    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
	    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM [dallas] YYYY',
	        LLL : 'D. MMMM [dallas] YYYY HH.mm',
	        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'
	    },
	    meridiemParse: /d\'o|d\'a/i,
	    isPM : function (input) {
	        return 'd\'o' === input.toLowerCase();
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'd\'o' : 'D\'O';
	        } else {
	            return isLower ? 'd\'a' : 'D\'A';
	        }
	    },
	    calendar : {
	        sameDay : '[oxhi à] LT',
	        nextDay : '[demà à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[ieiri à] LT',
	        lastWeek : '[sür el] dddd [lasteu à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'osprei %s',
	        past : 'ja%s',
	        s : processRelativeTime,
	        m : processRelativeTime,
	        mm : processRelativeTime,
	        h : processRelativeTime,
	        hh : processRelativeTime,
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's': ['viensas secunds', '\'iensas secunds'],
	        'm': ['\'n míut', '\'iens míut'],
	        'mm': [number + ' míuts', '' + number + ' míuts'],
	        'h': ['\'n þora', '\'iensa þora'],
	        'hh': [number + ' þoras', '' + number + ' þoras'],
	        'd': ['\'n ziua', '\'iensa ziua'],
	        'dd': [number + ' ziuas', '' + number + ' ziuas'],
	        'M': ['\'n mes', '\'iens mes'],
	        'MM': [number + ' mesen', '' + number + ' mesen'],
	        'y': ['\'n ar', '\'iens ar'],
	        'yy': [number + ' ars', '' + number + ' ars']
	    };
	    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);
	}
	
	return tzl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Central Atlas Tamazight [tzm]
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tzm = moment.defineLocale('tzm', {
	    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
	    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
	    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
	        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',
	        nextWeek: 'dddd [ⴴ] LT',
	        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',
	        lastWeek: 'dddd [ⴴ] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',
	        past : 'ⵢⴰⵏ %s',
	        s : 'ⵉⵎⵉⴽ',
	        m : 'ⵎⵉⵏⵓⴺ',
	        mm : '%d ⵎⵉⵏⵓⴺ',
	        h : 'ⵙⴰⵄⴰ',
	        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',
	        d : 'ⴰⵙⵙ',
	        dd : '%d oⵙⵙⴰⵏ',
	        M : 'ⴰⵢoⵓⵔ',
	        MM : '%d ⵉⵢⵢⵉⵔⵏ',
	        y : 'ⴰⵙⴳⴰⵙ',
	        yy : '%d ⵉⵙⴳⴰⵙⵏ'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tzm;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Central Atlas Tamazight Latin [tzm-latn]
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tzmLatn = moment.defineLocale('tzm-latn', {
	    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
	    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
	    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[asdkh g] LT',
	        nextDay: '[aska g] LT',
	        nextWeek: 'dddd [g] LT',
	        lastDay: '[assant g] LT',
	        lastWeek: 'dddd [g] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'dadkh s yan %s',
	        past : 'yan %s',
	        s : 'imik',
	        m : 'minuḍ',
	        mm : '%d minuḍ',
	        h : 'saɛa',
	        hh : '%d tassaɛin',
	        d : 'ass',
	        dd : '%d ossan',
	        M : 'ayowr',
	        MM : '%d iyyirn',
	        y : 'asgas',
	        yy : '%d isgasn'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tzmLatn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Ukrainian [uk]
	//! author : zemlanin : https://github.com/zemlanin
	//! Author : Menelion Elensúle : https://github.com/Oire
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
	        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',
	        'dd': 'день_дні_днів',
	        'MM': 'місяць_місяці_місяців',
	        'yy': 'рік_роки_років'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'хвилина' : 'хвилину';
	    }
	    else if (key === 'h') {
	        return withoutSuffix ? 'година' : 'годину';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	function weekdaysCaseReplace(m, format) {
	    var weekdays = {
	        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
	        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
	        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
	    };
	
	    if (!m) {
	        return weekdays['nominative'];
	    }
	
	    var nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
	        'accusative' :
	        ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
	            'genitive' :
	            'nominative');
	    return weekdays[nounCase][m.day()];
	}
	function processHoursFunction(str) {
	    return function () {
	        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
	    };
	}
	
	var uk = moment.defineLocale('uk', {
	    months : {
	        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),
	        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')
	    },
	    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),
	    weekdays : weekdaysCaseReplace,
	    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY р.',
	        LLL : 'D MMMM YYYY р., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY р., HH:mm'
	    },
	    calendar : {
	        sameDay: processHoursFunction('[Сьогодні '),
	        nextDay: processHoursFunction('[Завтра '),
	        lastDay: processHoursFunction('[Вчора '),
	        nextWeek: processHoursFunction('[У] dddd ['),
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 5:
	                case 6:
	                    return processHoursFunction('[Минулої] dddd [').call(this);
	                case 1:
	                case 2:
	                case 4:
	                    return processHoursFunction('[Минулого] dddd [').call(this);
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'за %s',
	        past : '%s тому',
	        s : 'декілька секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : 'годину',
	        hh : relativeTimeWithPlural,
	        d : 'день',
	        dd : relativeTimeWithPlural,
	        M : 'місяць',
	        MM : relativeTimeWithPlural,
	        y : 'рік',
	        yy : relativeTimeWithPlural
	    },
	    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
	    meridiemParse: /ночі|ранку|дня|вечора/,
	    isPM: function (input) {
	        return /^(дня|вечора)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночі';
	        } else if (hour < 12) {
	            return 'ранку';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечора';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	            case 'w':
	            case 'W':
	                return number + '-й';
	            case 'D':
	                return number + '-го';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return uk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Urdu [ur]
	//! author : Sawood Alam : https://github.com/ibnesayeed
	//! author : Zack : https://github.com/ZackVision
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'جنوری',
	    'فروری',
	    'مارچ',
	    'اپریل',
	    'مئی',
	    'جون',
	    'جولائی',
	    'اگست',
	    'ستمبر',
	    'اکتوبر',
	    'نومبر',
	    'دسمبر'
	];
	var days = [
	    'اتوار',
	    'پیر',
	    'منگل',
	    'بدھ',
	    'جمعرات',
	    'جمعہ',
	    'ہفتہ'
	];
	
	var ur = moment.defineLocale('ur', {
	    months : months,
	    monthsShort : months,
	    weekdays : days,
	    weekdaysShort : days,
	    weekdaysMin : days,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd، D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /صبح|شام/,
	    isPM : function (input) {
	        return 'شام' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'صبح';
	        }
	        return 'شام';
	    },
	    calendar : {
	        sameDay : '[آج بوقت] LT',
	        nextDay : '[کل بوقت] LT',
	        nextWeek : 'dddd [بوقت] LT',
	        lastDay : '[گذشتہ روز بوقت] LT',
	        lastWeek : '[گذشتہ] dddd [بوقت] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s بعد',
	        past : '%s قبل',
	        s : 'چند سیکنڈ',
	        m : 'ایک منٹ',
	        mm : '%d منٹ',
	        h : 'ایک گھنٹہ',
	        hh : '%d گھنٹے',
	        d : 'ایک دن',
	        dd : '%d دن',
	        M : 'ایک ماہ',
	        MM : '%d ماہ',
	        y : 'ایک سال',
	        yy : '%d سال'
	    },
	    preparse: function (string) {
	        return string.replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/,/g, '،');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ur;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Uzbek [uz]
	//! author : Sardor Muminov : https://github.com/muminoff
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var uz = moment.defineLocale('uz', {
	    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),
	    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),
	    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),
	    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),
	    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'D MMMM YYYY, dddd HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бугун соат] LT [да]',
	        nextDay : '[Эртага] LT [да]',
	        nextWeek : 'dddd [куни соат] LT [да]',
	        lastDay : '[Кеча соат] LT [да]',
	        lastWeek : '[Утган] dddd [куни соат] LT [да]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'Якин %s ичида',
	        past : 'Бир неча %s олдин',
	        s : 'фурсат',
	        m : 'бир дакика',
	        mm : '%d дакика',
	        h : 'бир соат',
	        hh : '%d соат',
	        d : 'бир кун',
	        dd : '%d кун',
	        M : 'бир ой',
	        MM : '%d ой',
	        y : 'бир йил',
	        yy : '%d йил'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return uz;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Uzbek Latin [uz-latn]
	//! author : Rasulbek Mirzayev : github.com/Rasulbeeek
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var uzLatn = moment.defineLocale('uz-latn', {
	    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),
	    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),
	    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),
	    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),
	    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'D MMMM YYYY, dddd HH:mm'
	    },
	    calendar : {
	        sameDay : '[Bugun soat] LT [da]',
	        nextDay : '[Ertaga] LT [da]',
	        nextWeek : 'dddd [kuni soat] LT [da]',
	        lastDay : '[Kecha soat] LT [da]',
	        lastWeek : '[O\'tgan] dddd [kuni soat] LT [da]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'Yaqin %s ichida',
	        past : 'Bir necha %s oldin',
	        s : 'soniya',
	        m : 'bir daqiqa',
	        mm : '%d daqiqa',
	        h : 'bir soat',
	        hh : '%d soat',
	        d : 'bir kun',
	        dd : '%d kun',
	        M : 'bir oy',
	        MM : '%d oy',
	        y : 'bir yil',
	        yy : '%d yil'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return uzLatn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Vietnamese [vi]
	//! author : Bang Nguyen : https://github.com/bangnk
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var vi = moment.defineLocale('vi', {
	    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),
	    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),
	    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
	    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
	    weekdaysParseExact : true,
	    meridiemParse: /sa|ch/i,
	    isPM : function (input) {
	        return /^ch$/i.test(input);
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower ? 'sa' : 'SA';
	        } else {
	            return isLower ? 'ch' : 'CH';
	        }
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM [năm] YYYY',
	        LLL : 'D MMMM [năm] YYYY HH:mm',
	        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
	        l : 'DD/M/YYYY',
	        ll : 'D MMM YYYY',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd, D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hôm nay lúc] LT',
	        nextDay: '[Ngày mai lúc] LT',
	        nextWeek: 'dddd [tuần tới lúc] LT',
	        lastDay: '[Hôm qua lúc] LT',
	        lastWeek: 'dddd [tuần rồi lúc] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s tới',
	        past : '%s trước',
	        s : 'vài giây',
	        m : 'một phút',
	        mm : '%d phút',
	        h : 'một giờ',
	        hh : '%d giờ',
	        d : 'một ngày',
	        dd : '%d ngày',
	        M : 'một tháng',
	        MM : '%d tháng',
	        y : 'một năm',
	        yy : '%d năm'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}/,
	    ordinal : function (number) {
	        return number;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return vi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Pseudo [x-pseudo]
	//! author : Andrew Hood : https://github.com/andrewhood125
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var xPseudo = moment.defineLocale('x-pseudo', {
	    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),
	    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),
	    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),
	    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[T~ódá~ý át] LT',
	        nextDay : '[T~ómó~rró~w át] LT',
	        nextWeek : 'dddd [át] LT',
	        lastDay : '[Ý~ést~érdá~ý át] LT',
	        lastWeek : '[L~ást] dddd [át] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'í~ñ %s',
	        past : '%s á~gó',
	        s : 'á ~féw ~sécó~ñds',
	        m : 'á ~míñ~úté',
	        mm : '%d m~íñú~tés',
	        h : 'á~ñ hó~úr',
	        hh : '%d h~óúrs',
	        d : 'á ~dáý',
	        dd : '%d d~áýs',
	        M : 'á ~móñ~th',
	        MM : '%d m~óñt~hs',
	        y : 'á ~ýéár',
	        yy : '%d ý~éárs'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return xPseudo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Yoruba Nigeria [yo]
	//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var yo = moment.defineLocale('yo', {
	    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),
	    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),
	    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),
	    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),
	    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Ònì ni] LT',
	        nextDay : '[Ọ̀la ni] LT',
	        nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT',
	        lastDay : '[Àna ni] LT',
	        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ní %s',
	        past : '%s kọjá',
	        s : 'ìsẹjú aayá die',
	        m : 'ìsẹjú kan',
	        mm : 'ìsẹjú %d',
	        h : 'wákati kan',
	        hh : 'wákati %d',
	        d : 'ọjọ́ kan',
	        dd : 'ọjọ́ %d',
	        M : 'osù kan',
	        MM : 'osù %d',
	        y : 'ọdún kan',
	        yy : 'ọdún %d'
	    },
	    dayOfMonthOrdinalParse : /ọjọ́\s\d{1,2}/,
	    ordinal : 'ọjọ́ %d',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return yo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chinese (China) [zh-cn]
	//! author : suupic : https://github.com/suupic
	//! author : Zeno Zeng : https://github.com/zenozeng
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhCn = moment.defineLocale('zh-cn', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日Ah点mm分',
	        LLLL : 'YYYY年MMMD日ddddAh点mm分',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日 HH:mm',
	        llll : 'YYYY年MMMD日dddd HH:mm'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' ||
	                meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        } else {
	            // '中午'
	            return hour >= 11 ? hour : hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd':
	            case 'D':
	            case 'DDD':
	                return number + '日';
	            case 'M':
	                return number + '月';
	            case 'w':
	            case 'W':
	                return number + '周';
	            default:
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s内',
	        past : '%s前',
	        s : '几秒',
	        m : '1 分钟',
	        mm : '%d 分钟',
	        h : '1 小时',
	        hh : '%d 小时',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 个月',
	        MM : '%d 个月',
	        y : '1 年',
	        yy : '%d 年'
	    },
	    week : {
	        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return zhCn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chinese (Hong Kong) [zh-hk]
	//! author : Ben : https://github.com/ben-lin
	//! author : Chris Lam : https://github.com/hehachris
	//! author : Konstantin : https://github.com/skfd
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhHk = moment.defineLocale('zh-hk', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日 HH:mm',
	        LLLL : 'YYYY年MMMD日dddd HH:mm',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日 HH:mm',
	        llll : 'YYYY年MMMD日dddd HH:mm'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '中午') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd' :
	            case 'D' :
	            case 'DDD' :
	                return number + '日';
	            case 'M' :
	                return number + '月';
	            case 'w' :
	            case 'W' :
	                return number + '週';
	            default :
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s內',
	        past : '%s前',
	        s : '幾秒',
	        m : '1 分鐘',
	        mm : '%d 分鐘',
	        h : '1 小時',
	        hh : '%d 小時',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 個月',
	        MM : '%d 個月',
	        y : '1 年',
	        yy : '%d 年'
	    }
	});
	
	return zhHk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chinese (Taiwan) [zh-tw]
	//! author : Ben : https://github.com/ben-lin
	//! author : Chris Lam : https://github.com/hehachris
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(234)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhTw = moment.defineLocale('zh-tw', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日 HH:mm',
	        LLLL : 'YYYY年MMMD日dddd HH:mm',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日 HH:mm',
	        llll : 'YYYY年MMMD日dddd HH:mm'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '中午') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd' :
	            case 'D' :
	            case 'DDD' :
	                return number + '日';
	            case 'M' :
	                return number + '月';
	            case 'w' :
	            case 'W' :
	                return number + '週';
	            default :
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s內',
	        past : '%s前',
	        s : '幾秒',
	        m : '1 分鐘',
	        mm : '%d 分鐘',
	        h : '1 小時',
	        hh : '%d 小時',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 個月',
	        MM : '%d 個月',
	        y : '1 年',
	        yy : '%d 年'
	    }
	});
	
	return zhTw;
	
	})));


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

	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(process) {/*!
	 * numbro.js
	 * version : 1.11.0
	 * author : Företagsplatsen AB
	 * license : MIT
	 * http://www.foretagsplatsen.se
	 */
	
	(function () {
	    'use strict';
	
	    /************************************
	        Constants
	    ************************************/
	
	    var numbro,
	        VERSION = '1.11.0',
	        binarySuffixes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'],
	        decimalSuffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
	        bytes = {
	            general: { scale: 1024, suffixes: decimalSuffixes, marker: 'bd' },
	            binary:  { scale: 1024, suffixes: binarySuffixes, marker: 'b' },
	            decimal: { scale: 1000, suffixes: decimalSuffixes, marker: 'd' }
	        },
	        // general must be before the others because it reuses their characters!
	        byteFormatOrder = [ bytes.general, bytes.binary, bytes.decimal ],
	    // internal storage for culture config files
	        cultures = {},
	    // Todo: Remove in 2.0.0
	        languages = cultures,
	        currentCulture = 'en-US',
	        zeroFormat = null,
	        defaultFormat = '0,0',
	        defaultCurrencyFormat = '0$',
	        // check for nodeJS
	        hasModule = (typeof module !== 'undefined' && module.exports),
	    // default culture
	        enUS = {
	            delimiters: {
	                thousands: ',',
	                decimal: '.'
	            },
	            abbreviations: {
	                thousand: 'k',
	                million: 'm',
	                billion: 'b',
	                trillion: 't'
	            },
	            ordinal: function(number) {
	                var b = number % 10;
	                return (~~(number % 100 / 10) === 1) ? 'th' :
	                    (b === 1) ? 'st' :
	                        (b === 2) ? 'nd' :
	                            (b === 3) ? 'rd' : 'th';
	            },
	            currency: {
	                symbol: '$',
	                position: 'prefix'
	            },
	            defaults: {
	                currencyFormat: ',0000 a'
	            },
	            formats: {
	                fourDigits: '0000 a',
	                fullWithTwoDecimals: '$ ,0.00',
	                fullWithTwoDecimalsNoCurrency: ',0.00'
	            }
	        };
	
	    /************************************
	        Constructors
	    ************************************/
	
	
	    // Numbro prototype object
	    function Numbro(number) {
	        this._value = number;
	    }
	
	    function numberLength(number) {
	        if (number === 0) { return 1; }
	        return Math.floor(Math.log(Math.abs(number)) / Math.LN10) + 1;
	    }
	
	    function zeroes(count) {
	        var i, ret = '';
	
	        for (i = 0; i < count; i++) {
	            ret += '0';
	        }
	
	        return ret;
	    }
	    /**
	     * Implementation of toFixed() for numbers with exponents
	     * This function may return negative representations for zero values e.g. "-0.0"
	     */
	    function toFixedLargeSmall(value, precision) {
	        var mantissa,
	            beforeDec,
	            afterDec,
	            exponent,
	            prefix,
	            endStr,
	            zerosStr,
	            str;
	
	        str = value.toString();
	
	        mantissa = str.split('e')[0];
	        exponent = str.split('e')[1];
	
	        beforeDec = mantissa.split('.')[0];
	        afterDec = mantissa.split('.')[1] || '';
	
	        if (+exponent > 0) {
	            // exponent is positive - add zeros after the numbers
	            str = beforeDec + afterDec + zeroes(exponent - afterDec.length);
	        } else {
	            // exponent is negative
	
	            if (+beforeDec < 0) {
	                prefix = '-0';
	            } else {
	                prefix = '0';
	            }
	
	            // tack on the decimal point if needed
	            if (precision > 0) {
	                prefix += '.';
	            }
	
	            zerosStr = zeroes((-1 * exponent) - 1);
	            // substring off the end to satisfy the precision
	            endStr = (zerosStr + Math.abs(beforeDec) + afterDec).substr(0, precision);
	            str = prefix + endStr;
	        }
	
	        // only add percision 0's if the exponent is positive
	        if (+exponent > 0 && precision > 0) {
	            str += '.' + zeroes(precision);
	        }
	
	        return str;
	    }
	
	    /**
	     * Implementation of toFixed() that treats floats more like decimals
	     *
	     * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
	     * problems for accounting- and finance-related software.
	     *
	     * Also removes negative signs for zero-formatted numbers. e.g. -0.01 w/ precision 1 -> 0.0
	     */
	    function toFixed(value, precision, roundingFunction, optionals) {
	        var power = Math.pow(10, precision),
	            optionalsRegExp,
	            output;
	
	        if (value.toString().indexOf('e') > -1) {
	            // toFixed returns scientific notation for numbers above 1e21 and below 1e-7
	            output = toFixedLargeSmall(value, precision);
	            // remove the leading negative sign if it exists and should not be present (e.g. -0.00)
	            if (output.charAt(0) === '-' && +output >= 0) {
	                output = output.substr(1); // chop off the '-'
	            }
	        }
	        else {
	            // Multiply up by precision, round accurately, then divide and use native toFixed():
	            output = (roundingFunction(value + 'e+' + precision) / power).toFixed(precision);
	        }
	
	        if (optionals) {
	            optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
	            output = output.replace(optionalsRegExp, '');
	        }
	
	        return output;
	    }
	
	    /************************************
	        Formatting
	    ************************************/
	
	    // determine what type of formatting we need to do
	    function formatNumbro(n, format, roundingFunction) {
	        var output,
	            escapedFormat = format.replace(/\{[^\{\}]*\}/g, '');
	
	        // figure out what kind of format we are dealing with
	        if (escapedFormat.indexOf('$') > -1) { // currency!!!!!
	            output = formatCurrency(n, cultures[currentCulture].currency.symbol, format, roundingFunction);
	        } else if (escapedFormat.indexOf('%') > -1) { // percentage
	            output = formatPercentage(n, format, roundingFunction);
	        } else if (escapedFormat.indexOf(':') > -1) { // time
	            output = formatTime(n, format);
	        } else { // plain ol' numbers or bytes
	            output = formatNumber(n._value, format, roundingFunction);
	        }
	
	        // return string
	        return output;
	    }
	
	    // revert to number
	    function unformatNumbro(n, string) {
	        var stringOriginal = string,
	            thousandRegExp,
	            millionRegExp,
	            billionRegExp,
	            trillionRegExp,
	            bytesMultiplier = false,
	            power;
	
	        if (string.indexOf(':') > -1) {
	            n._value = unformatTime(string);
	        } else {
	            if (string === zeroFormat) {
	                n._value = 0;
	            } else {
	                if (cultures[currentCulture].delimiters.decimal !== '.') {
	                    string = string.replace(/\./g, '').replace(cultures[currentCulture].delimiters.decimal, '.');
	                }
	
	                // see if abbreviations are there so that we can multiply to the correct number
	                thousandRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.thousand +
	                    '(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
	                millionRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.million +
	                    '(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
	                billionRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.billion +
	                    '(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
	                trillionRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.trillion +
	                    '(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
	
	                // see if bytes are there so that we can multiply to the correct number
	                for (power = 1; power < binarySuffixes.length && !bytesMultiplier; ++power) {
	                    if (string.indexOf(binarySuffixes[power]) > -1) {
	                        bytesMultiplier = Math.pow(1024, power);
	                    } else if (string.indexOf(decimalSuffixes[power]) > -1) {
	                        bytesMultiplier = Math.pow(1000, power);
	                    }
	                }
	
	                var str = string.replace(/[^0-9\.]+/g, '');
	                if (str === '') {
	                    // An empty string is not a number.
	                    n._value = NaN;
	
	                } else {
	                    // do some math to create our number
	                    n._value = ((bytesMultiplier) ? bytesMultiplier : 1) *
	                        ((stringOriginal.match(thousandRegExp)) ? Math.pow(10, 3) : 1) *
	                        ((stringOriginal.match(millionRegExp)) ? Math.pow(10, 6) : 1) *
	                        ((stringOriginal.match(billionRegExp)) ? Math.pow(10, 9) : 1) *
	                        ((stringOriginal.match(trillionRegExp)) ? Math.pow(10, 12) : 1) *
	                        ((string.indexOf('%') > -1) ? 0.01 : 1) *
	                        (((string.split('-').length +
	                            Math.min(string.split('(').length - 1, string.split(')').length - 1)) % 2) ? 1 : -1) *
	                        Number(str);
	
	                    // round if we are talking about bytes
	                    n._value = (bytesMultiplier) ? Math.ceil(n._value) : n._value;
	                }
	            }
	        }
	        return n._value;
	    }
	
	    function formatCurrency(n, currencySymbol, originalFormat, roundingFunction) {
	        var format = originalFormat,
	            symbolIndex = format.indexOf('$'),
	            openParenIndex = format.indexOf('('),
	            plusSignIndex = format.indexOf('+'),
	            minusSignIndex = format.indexOf('-'),
	            space = '',
	            decimalSeparator = '',
	            spliceIndex,
	            output;
	
	        if(format.indexOf('$') === -1){
	            // Use defaults instead of the format provided
	            if (cultures[currentCulture].currency.position === 'infix') {
	                decimalSeparator = currencySymbol;
	                if (cultures[currentCulture].currency.spaceSeparated) {
	                    decimalSeparator = ' ' + decimalSeparator + ' ';
	                }
	            } else if (cultures[currentCulture].currency.spaceSeparated) {
	                space = ' ';
	            }
	        } else {
	            // check for space before or after currency
	            if (format.indexOf(' $') > -1) {
	                space = ' ';
	                format = format.replace(' $', '');
	            } else if (format.indexOf('$ ') > -1) {
	                space = ' ';
	                format = format.replace('$ ', '');
	            } else {
	                format = format.replace('$', '');
	            }
	        }
	
	        // Format The Number
	        output = formatNumber(n._value, format, roundingFunction, decimalSeparator);
	
	        if (originalFormat.indexOf('$') === -1) {
	            // Use defaults instead of the format provided
	            switch (cultures[currentCulture].currency.position) {
	                case 'postfix':
	                    if (output.indexOf(')') > -1) {
	                        output = output.split('');
	                        output.splice(-1, 0, space + currencySymbol);
	                        output = output.join('');
	                    } else {
	                        output = output + space + currencySymbol;
	                    }
	                    break;
	                case 'infix':
	                    break;
	                case 'prefix':
	                    if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
	                        output = output.split('');
	                        spliceIndex = Math.max(openParenIndex, minusSignIndex) + 1;
	
	                        output.splice(spliceIndex, 0, currencySymbol + space);
	                        output = output.join('');
	                    } else {
	                        output = currencySymbol + space + output;
	                    }
	                    break;
	                default:
	                    throw Error('Currency position should be among ["prefix", "infix", "postfix"]');
	            }
	        } else {
	            // position the symbol
	            if (symbolIndex <= 1) {
	                if (output.indexOf('(') > -1 || output.indexOf('+') > -1 || output.indexOf('-') > -1) {
	                    output = output.split('');
	                    spliceIndex = 1;
	                    if (symbolIndex < openParenIndex || symbolIndex < plusSignIndex || symbolIndex < minusSignIndex) {
	                        // the symbol appears before the "(", "+" or "-"
	                        spliceIndex = 0;
	                    }
	                    output.splice(spliceIndex, 0, currencySymbol + space);
	                    output = output.join('');
	                } else {
	                    output = currencySymbol + space + output;
	                }
	            } else {
	                if (output.indexOf(')') > -1) {
	                    output = output.split('');
	                    output.splice(-1, 0, space + currencySymbol);
	                    output = output.join('');
	                } else {
	                    output = output + space + currencySymbol;
	                }
	            }
	        }
	
	        return output;
	    }
	
	    function formatForeignCurrency(n, foreignCurrencySymbol, originalFormat, roundingFunction) {
	        return formatCurrency(n, foreignCurrencySymbol, originalFormat, roundingFunction);
	    }
	
	    function formatPercentage(n, format, roundingFunction) {
	        var space = '',
	            output,
	            value = n._value * 100;
	
	        // check for space before %
	        if (format.indexOf(' %') > -1) {
	            space = ' ';
	            format = format.replace(' %', '');
	        } else {
	            format = format.replace('%', '');
	        }
	
	        output = formatNumber(value, format, roundingFunction);
	
	        if (output.indexOf(')') > -1) {
	            output = output.split('');
	            output.splice(-1, 0, space + '%');
	            output = output.join('');
	        } else {
	            output = output + space + '%';
	        }
	
	        return output;
	    }
	
	    function formatTime(n) {
	        var hours = Math.floor(n._value / 60 / 60),
	            minutes = Math.floor((n._value - (hours * 60 * 60)) / 60),
	            seconds = Math.round(n._value - (hours * 60 * 60) - (minutes * 60));
	        return hours + ':' +
	            ((minutes < 10) ? '0' + minutes : minutes) + ':' +
	            ((seconds < 10) ? '0' + seconds : seconds);
	    }
	
	    function unformatTime(string) {
	        var timeArray = string.split(':'),
	            seconds = 0;
	        // turn hours and minutes into seconds and add them all up
	        if (timeArray.length === 3) {
	            // hours
	            seconds = seconds + (Number(timeArray[0]) * 60 * 60);
	            // minutes
	            seconds = seconds + (Number(timeArray[1]) * 60);
	            // seconds
	            seconds = seconds + Number(timeArray[2]);
	        } else if (timeArray.length === 2) {
	            // minutes
	            seconds = seconds + (Number(timeArray[0]) * 60);
	            // seconds
	            seconds = seconds + Number(timeArray[1]);
	        }
	        return Number(seconds);
	    }
	
	    function formatByteUnits (value, suffixes, scale) {
	        var suffix = suffixes[0],
	            power,
	            min,
	            max,
	            abs = Math.abs(value);
	
	        if (abs >= scale) {
	            for (power = 1; power < suffixes.length; ++power) {
	                min = Math.pow(scale, power);
	                max = Math.pow(scale, power + 1);
	
	                if (abs >= min && abs < max) {
	                    suffix = suffixes[power];
	                    value = value / min;
	                    break;
	                }
	            }
	
	            // values greater than or equal to [scale] YB never set the suffix
	            if (suffix === suffixes[0]) {
	                value = value / Math.pow(scale, suffixes.length - 1);
	                suffix = suffixes[suffixes.length - 1];
	            }
	        }
	
	        return { value: value, suffix: suffix };
	    }
	
	    function formatNumber (value, format, roundingFunction, sep) {
	        var negP = false,
	            signed = false,
	            optDec = false,
	            abbr = '',
	            abbrK = false, // force abbreviation to thousands
	            abbrM = false, // force abbreviation to millions
	            abbrB = false, // force abbreviation to billions
	            abbrT = false, // force abbreviation to trillions
	            abbrForce = false, // force abbreviation
	            bytes = '',
	            byteFormat,
	            units,
	            ord = '',
	            abs = Math.abs(value),
	            totalLength,
	            length,
	            minimumPrecision,
	            pow,
	            w,
	            intPrecision,
	            precision,
	            prefix,
	            postfix,
	            thousands,
	            d = '',
	            forcedNeg = false,
	            neg = false,
	            indexOpenP,
	            indexMinus,
	            paren = '',
	            minlen,
	            i;
	
	        // check if number is zero and a custom zero format has been set
	        if (value === 0 && zeroFormat !== null) {
	            return zeroFormat;
	        }
	
	        if (!isFinite(value)) {
	            return '' + value;
	        }
	
	        if (format.indexOf('{') === 0) {
	            var end = format.indexOf('}');
	            if (end === -1) {
	                throw Error('Format should also contain a "}"');
	            }
	            prefix = format.slice(1, end);
	            format = format.slice(end + 1);
	        } else {
	            prefix = '';
	        }
	
	        if (format.indexOf('}') === format.length - 1 && format.length) {
	            var start = format.indexOf('{');
	            if (start === -1) {
	                throw Error('Format should also contain a "{"');
	            }
	            postfix = format.slice(start + 1, -1);
	            format = format.slice(0, start + 1);
	        } else {
	            postfix = '';
	        }
	
	        // check for min length
	        var info;
	        if (format.indexOf('.') === -1) {
	            info = format.match(/([0-9]+).*/);
	        } else {
	            info = format.match(/([0-9]+)\..*/);
	        }
	        minlen = info === null ? -1 : info[1].length;
	
	        // see if we should use parentheses for negative number or if we should prefix with a sign
	        // if both are present we default to parentheses
	        if (format.indexOf('-') !== -1) {
	            forcedNeg = true;
	        }
	        if (format.indexOf('(') > -1) {
	            negP = true;
	            format = format.slice(1, -1);
	        } else if (format.indexOf('+') > -1) {
	            signed = true;
	            format = format.replace(/\+/g, '');
	        }
	
	        // see if abbreviation is wanted
	        if (format.indexOf('a') > -1) {
	            intPrecision = format.split('.')[0].match(/[0-9]+/g) || ['0'];
	            intPrecision = parseInt(intPrecision[0], 10);
	
	            // check if abbreviation is specified
	            abbrK = format.indexOf('aK') >= 0;
	            abbrM = format.indexOf('aM') >= 0;
	            abbrB = format.indexOf('aB') >= 0;
	            abbrT = format.indexOf('aT') >= 0;
	            abbrForce = abbrK || abbrM || abbrB || abbrT;
	
	            // check for space before abbreviation
	            if (format.indexOf(' a') > -1) {
	                abbr = ' ';
	                format = format.replace(' a', '');
	            } else {
	                format = format.replace('a', '');
	            }
	
	            totalLength = numberLength(value);
	            minimumPrecision = totalLength % 3;
	            minimumPrecision = minimumPrecision === 0 ? 3 : minimumPrecision;
	
	            if (intPrecision && abs !== 0) {
	                pow = 3 * ~~((Math.min(intPrecision, totalLength) - minimumPrecision) / 3);
	                abs = abs / Math.pow(10, pow);
	            }
	
	            if (totalLength !== intPrecision) {
	                if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {
	                    // trillion
	                    abbr = abbr + cultures[currentCulture].abbreviations.trillion;
	                    value = value / Math.pow(10, 12);
	                } else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {
	                    // billion
	                    abbr = abbr + cultures[currentCulture].abbreviations.billion;
	                    value = value / Math.pow(10, 9);
	                } else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {
	                    // million
	                    abbr = abbr + cultures[currentCulture].abbreviations.million;
	                    value = value / Math.pow(10, 6);
	                } else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {
	                    // thousand
	                    abbr = abbr + cultures[currentCulture].abbreviations.thousand;
	                    value = value / Math.pow(10, 3);
	                }
	            }
	
	            length = numberLength(value);
	            if (intPrecision && length < intPrecision && format.indexOf('.') === -1) {
	                format += '[.]';
	                format += zeroes(intPrecision - length);
	            }
	        }
	
	        // see if we are formatting
	        //   binary-decimal bytes (1024 MB), binary bytes (1024 MiB), or decimal bytes (1000 MB)
	        for (i = 0; i < byteFormatOrder.length; ++i) {
	            byteFormat = byteFormatOrder[i];
	
	            if (format.indexOf(byteFormat.marker) > -1) {
	                // check for space before
	                if (format.indexOf(' ' + byteFormat.marker) >-1) {
	                    bytes = ' ';
	                }
	
	                // remove the marker (with the space if it had one)
	                format = format.replace(bytes + byteFormat.marker, '');
	
	                units = formatByteUnits(value, byteFormat.suffixes, byteFormat.scale);
	
	                value = units.value;
	                bytes = bytes + units.suffix;
	
	                break;
	            }
	        }
	
	        // see if ordinal is wanted
	        if (format.indexOf('o') > -1) {
	            // check for space before
	            if (format.indexOf(' o') > -1) {
	                ord = ' ';
	                format = format.replace(' o', '');
	            } else {
	                format = format.replace('o', '');
	            }
	
	            if (cultures[currentCulture].ordinal) {
	                ord = ord + cultures[currentCulture].ordinal(value);
	            }
	        }
	
	        if (format.indexOf('[.]') > -1) {
	            optDec = true;
	            format = format.replace('[.]', '.');
	        }
	
	        precision = format.split('.')[1];
	        thousands = format.indexOf(',');
	
	        if (precision) {
	            var dSplit = [];
	
	            if (precision.indexOf('*') !== -1) {
	                d = value.toString();
	                dSplit = d.split('.');
	                if (dSplit.length > 1) {
	                    d = toFixed(value, dSplit[1].length, roundingFunction);
	                }
	            } else {
	                if (precision.indexOf('[') > -1) {
	                    precision = precision.replace(']', '');
	                    precision = precision.split('[');
	                    d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction,
	                        precision[1].length);
	                } else {
	                    d = toFixed(value, precision.length, roundingFunction);
	                }
	            }
	
	            dSplit = d.split('.');
	            w = dSplit[0];
	
	            if (dSplit.length > 1 && dSplit[1].length) {
	                var p = sep ? abbr + sep : cultures[currentCulture].delimiters.decimal;
	                d = p + dSplit[1];
	            } else {
	                d = '';
	            }
	
	            if (optDec && Number(d.slice(1)) === 0) {
	                d = '';
	            }
	        } else {
	            w = toFixed(value, 0, roundingFunction);
	        }
	
	        // format number
	        if (w.indexOf('-') > -1) {
	            w = w.slice(1);
	            neg = true;
	        }
	
	        if (w.length < minlen) {
	            w = zeroes(minlen - w.length) + w;
	        }
	
	        if (thousands > -1) {
	            w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' +
	                cultures[currentCulture].delimiters.thousands);
	        }
	
	        if (format.indexOf('.') === 0) {
	            w = '';
	        }
	
	        indexOpenP = format.indexOf('(');
	        indexMinus = format.indexOf('-');
	
	        if (indexOpenP < indexMinus) {
	            paren = ((negP && neg) ? '(' : '') + (((forcedNeg && neg) || (!negP && neg)) ? '-' : '');
	        } else {
	            paren = (((forcedNeg && neg) || (!negP && neg)) ? '-' : '') + ((negP && neg) ? '(' : '');
	        }
	
	        return prefix +
	            paren + ((!neg && signed && value !== 0) ? '+' : '') +
	            w + d +
	            ((ord) ? ord : '') +
	            ((abbr && !sep) ? abbr : '') +
	            ((bytes) ? bytes : '') +
	            ((negP && neg) ? ')' : '') +
	            postfix;
	    }
	
	    /************************************
	        Top Level Functions
	    ************************************/
	
	    numbro = function(input) {
	        if (numbro.isNumbro(input)) {
	            input = input.value();
	        } else if (typeof input === 'string' || typeof input === 'number') {
	            input = numbro.fn.unformat(input);
	        } else {
	            input = NaN;
	        }
	
	        return new Numbro(Number(input));
	    };
	
	    // version number
	    numbro.version = VERSION;
	
	    // compare numbro object
	    numbro.isNumbro = function(obj) {
	        return obj instanceof Numbro;
	    };
	
	    /**
	     * This function allow the user to set a new language with a fallback if
	     * the language does not exist. If no fallback language is provided,
	     * it fallbacks to english.
	     *
	     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
	     * `setCulture` should be used instead.
	     */
	    numbro.setLanguage = function(newLanguage, fallbackLanguage) {
	        console.warn('`setLanguage` is deprecated since version 1.6.0. Use `setCulture` instead');
	        var key = newLanguage,
	            prefix = newLanguage.split('-')[0],
	            matchingLanguage = null;
	        if (!languages[key]) {
	            Object.keys(languages).forEach(function(language) {
	                if (!matchingLanguage && language.split('-')[0] === prefix) {
	                    matchingLanguage = language;
	                }
	            });
	            key = matchingLanguage || fallbackLanguage || 'en-US';
	        }
	        chooseCulture(key);
	    };
	
	    /**
	     * This function allow the user to set a new culture with a fallback if
	     * the culture does not exist. If no fallback culture is provided,
	     * it falls back to "en-US".
	     */
	    numbro.setCulture = function(newCulture, fallbackCulture) {
	        var key = newCulture,
	            suffix = newCulture.split('-')[1],
	            matchingCulture = null;
	        if (!cultures[key]) {
	            if (suffix) {
	                Object.keys(cultures).forEach(function(language) {
	                    if (!matchingCulture && language.split('-')[1] === suffix) {
	                        matchingCulture = language;
	                    }
	                });
	            }
	
	            key = matchingCulture || fallbackCulture || 'en-US';
	        }
	        chooseCulture(key);
	    };
	
	    /**
	     * This function will load languages and then set the global language.  If
	     * no arguments are passed in, it will simply return the current global
	     * language key.
	     *
	     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
	     * `culture` should be used instead.
	     */
	    numbro.language = function(key, values) {
	        console.warn('`language` is deprecated since version 1.6.0. Use `culture` instead');
	
	        if (!key) {
	            return currentCulture;
	        }
	
	        if (key && !values) {
	            if (!languages[key]) {
	                throw new Error('Unknown language : ' + key);
	            }
	            chooseCulture(key);
	        }
	
	        if (values || !languages[key]) {
	            setCulture(key, values);
	        }
	
	        return numbro;
	    };
	
	    /**
	     * This function will load cultures and then set the global culture.  If
	     * no arguments are passed in, it will simply return the current global
	     * culture code.
	     */
	    numbro.culture = function(code, values) {
	        if (!code) {
	            return currentCulture;
	        }
	
	        if (code && !values) {
	            if (!cultures[code]) {
	                throw new Error('Unknown culture : ' + code);
	            }
	            chooseCulture(code);
	        }
	
	        if (values || !cultures[code]) {
	            setCulture(code, values);
	        }
	
	        return numbro;
	    };
	
	    /**
	     * This function provides access to the loaded language data.  If
	     * no arguments are passed in, it will simply return the current
	     * global language object.
	     *
	     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
	     * `culture` should be used instead.
	     */
	    numbro.languageData = function(key) {
	        console.warn('`languageData` is deprecated since version 1.6.0. Use `cultureData` instead');
	
	        if (!key) {
	            return languages[currentCulture];
	        }
	
	        if (!languages[key]) {
	            throw new Error('Unknown language : ' + key);
	        }
	
	        return languages[key];
	    };
	
	    /**
	     * This function provides access to the loaded culture data.  If
	     * no arguments are passed in, it will simply return the current
	     * global culture object.
	     */
	    numbro.cultureData = function(code) {
	        if (!code) {
	            return cultures[currentCulture];
	        }
	
	        if (!cultures[code]) {
	            throw new Error('Unknown culture : ' + code);
	        }
	
	        return cultures[code];
	    };
	
	    numbro.culture('en-US', enUS);
	
	    /**
	     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
	     * `cultures` should be used instead.
	     */
	    numbro.languages = function() {
	        console.warn('`languages` is deprecated since version 1.6.0. Use `cultures` instead');
	
	        return languages;
	    };
	
	    numbro.cultures = function() {
	        return cultures;
	    };
	
	    numbro.zeroFormat = function(format) {
	        zeroFormat = typeof(format) === 'string' ? format : null;
	    };
	
	    numbro.defaultFormat = function(format) {
	        defaultFormat = typeof(format) === 'string' ? format : '0.0';
	    };
	
	    numbro.defaultCurrencyFormat = function (format) {
	        defaultCurrencyFormat = typeof(format) === 'string' ? format : '0$';
	    };
	
	    numbro.validate = function(val, culture) {
	
	        var _decimalSep,
	            _thousandSep,
	            _currSymbol,
	            _valArray,
	            _abbrObj,
	            _thousandRegEx,
	            cultureData,
	            temp;
	
	        //coerce val to string
	        if (typeof val !== 'string') {
	            val += '';
	            if (console.warn) {
	                console.warn('Numbro.js: Value is not string. It has been co-erced to: ', val);
	            }
	        }
	
	        //trim whitespaces from either sides
	        val = val.trim();
	
	        //replace the initial '+' or '-' sign if present
	        val = val.replace(/^[+-]?/, '');
	
	        //if val is just digits return true
	        if ( !! val.match(/^\d+$/)) {
	            return true;
	        }
	
	        //if val is empty return false
	        if (val === '') {
	            return false;
	        }
	
	        //get the decimal and thousands separator from numbro.cultureData
	        try {
	            //check if the culture is understood by numbro. if not, default it to current culture
	            cultureData = numbro.cultureData(culture);
	        } catch (e) {
	            cultureData = numbro.cultureData(numbro.culture());
	        }
	
	        //setup the delimiters and currency symbol based on culture
	        _currSymbol = cultureData.currency.symbol;
	        _abbrObj = cultureData.abbreviations;
	        _decimalSep = cultureData.delimiters.decimal;
	        if (cultureData.delimiters.thousands === '.') {
	            _thousandSep = '\\.';
	        } else {
	            _thousandSep = cultureData.delimiters.thousands;
	        }
	
	        // validating currency symbol
	        temp = val.match(/^[^\d\.\,]+/);
	        if (temp !== null) {
	            val = val.substr(1);
	            if (temp[0] !== _currSymbol) {
	                return false;
	            }
	        }
	
	        //validating abbreviation symbol
	        temp = val.match(/[^\d]+$/);
	        if (temp !== null) {
	            val = val.slice(0, -1);
	            if (temp[0] !== _abbrObj.thousand && temp[0] !== _abbrObj.million &&
	                    temp[0] !== _abbrObj.billion && temp[0] !== _abbrObj.trillion) {
	                return false;
	            }
	        }
	
	        _thousandRegEx = new RegExp(_thousandSep + '{2}');
	
	        if (!val.match(/[^\d.,]/g)) {
	            _valArray = val.split(_decimalSep);
	            if (_valArray.length > 2) {
	                return false;
	            } else {
	                if (_valArray.length < 2) {
	                    return ( !! _valArray[0].match(/^\d+.*\d$/) && !_valArray[0].match(_thousandRegEx));
	                } else {
	                    if (_valArray[0] === '') {
	                        // for values without leading zero eg. .984
	                        return (!_valArray[0].match(_thousandRegEx) &&
	                            !!_valArray[1].match(/^\d+$/));
	
	                    } else if (_valArray[0].length === 1) {
	                        return ( !! _valArray[0].match(/^\d+$/) &&
	                            !_valArray[0].match(_thousandRegEx) &&
	                            !! _valArray[1].match(/^\d+$/));
	                    } else {
	                        return ( !! _valArray[0].match(/^\d+.*\d$/) &&
	                            !_valArray[0].match(_thousandRegEx) &&
	                            !! _valArray[1].match(/^\d+$/));
	                    }
	                }
	            }
	        }
	
	        return false;
	    };
	
	    /**
	     * * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
	     * `loadCulturesInNode` should be used instead.
	     */
	    numbro.loadLanguagesInNode = function() {
	        console.warn('`loadLanguagesInNode` is deprecated since version 1.6.0. Use `loadCulturesInNode` instead');
	
	        numbro.loadCulturesInNode();
	    };
	
	    numbro.loadCulturesInNode = function() {
	        // TODO: Rename the folder in 2.0.0
	        var cultures = __webpack_require__(352);
	
	        for(var langLocaleCode in cultures) {
	            if(langLocaleCode) {
	                numbro.culture(langLocaleCode, cultures[langLocaleCode]);
	            }
	        }
	    };
	
	    /************************************
	        Helpers
	    ************************************/
	
	    function setCulture(code, values) {
	        cultures[code] = values;
	    }
	
	    function chooseCulture(code) {
	        currentCulture = code;
	        var defaults = cultures[code].defaults;
	        if (defaults && defaults.format) {
	            numbro.defaultFormat(defaults.format);
	        }
	        if (defaults && defaults.currencyFormat) {
	            numbro.defaultCurrencyFormat(defaults.currencyFormat);
	        }
	    }
	
	    function inNodejsRuntime() {
	        return (typeof process !== 'undefined') &&
	            (process.browser === undefined) &&
	            process.title &&
	            (
	                process.title.indexOf('node') !== -1 ||
	                process.title.indexOf('meteor-tool') > 0 ||
	                process.title === 'grunt' ||
	                process.title === 'gulp'
	            ) &&
	            ("function" !== 'undefined');
	    }
	
	    /************************************
	        Floating-point helpers
	    ************************************/
	
	    // The floating-point helper functions and implementation
	    // borrows heavily from sinful.js: http://guipn.github.io/sinful.js/
	
	    /**
	     * Array.prototype.reduce for browsers that don't support it
	     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce#Compatibility
	     */
	    if ('function' !== typeof Array.prototype.reduce) {
	        Array.prototype.reduce = function(callback, optInitialValue) {
	
	            if (null === this || 'undefined' === typeof this) {
	                // At the moment all modern browsers, that support strict mode, have
	                // native implementation of Array.prototype.reduce. For instance, IE8
	                // does not support strict mode, so this check is actually useless.
	                throw new TypeError('Array.prototype.reduce called on null or undefined');
	            }
	
	            if ('function' !== typeof callback) {
	                throw new TypeError(callback + ' is not a function');
	            }
	
	            var index,
	                value,
	                length = this.length >>> 0,
	                isValueSet = false;
	
	            if (1 < arguments.length) {
	                value = optInitialValue;
	                isValueSet = true;
	            }
	
	            for (index = 0; length > index; ++index) {
	                if (this.hasOwnProperty(index)) {
	                    if (isValueSet) {
	                        value = callback(value, this[index], index, this);
	                    } else {
	                        value = this[index];
	                        isValueSet = true;
	                    }
	                }
	            }
	
	            if (!isValueSet) {
	                throw new TypeError('Reduce of empty array with no initial value');
	            }
	
	            return value;
	        };
	    }
	
	
	    /**
	     * Computes the multiplier necessary to make x >= 1,
	     * effectively eliminating miscalculations caused by
	     * finite precision.
	     */
	    function multiplier(x) {
	        var parts = x.toString().split('.');
	        if (parts.length < 2) {
	            return 1;
	        }
	        return Math.pow(10, parts[1].length);
	    }
	
	    /**
	     * Given a variable number of arguments, returns the maximum
	     * multiplier that must be used to normalize an operation involving
	     * all of them.
	     */
	    function correctionFactor() {
	        var args = Array.prototype.slice.call(arguments);
	        return args.reduce(function(prev, next) {
	            var mp = multiplier(prev),
	                mn = multiplier(next);
	            return mp > mn ? mp : mn;
	        }, -Infinity);
	    }
	
	    /************************************
	        Numbro Prototype
	    ************************************/
	
	
	    numbro.fn = Numbro.prototype = {
	
	        clone: function() {
	            return numbro(this);
	        },
	
	        format: function(inputString, roundingFunction) {
	            return formatNumbro(this,
	                inputString ? inputString : defaultFormat,
	                (roundingFunction !== undefined) ? roundingFunction : Math.round
	            );
	        },
	
	        formatCurrency: function(inputString, roundingFunction) {
	            return formatCurrency(this,
	                cultures[currentCulture].currency.symbol,
	                inputString ? inputString : defaultCurrencyFormat,
	                (roundingFunction !== undefined) ? roundingFunction : Math.round
	            );
	        },
	
	        formatForeignCurrency: function(currencySymbol, inputString, roundingFunction) {
	            return formatForeignCurrency(this,
	                currencySymbol,
	                inputString ? inputString : defaultCurrencyFormat,
	                (roundingFunction !== undefined) ? roundingFunction : Math.round
	            );
	        },
	
	        unformat: function(inputString) {
	            if (typeof inputString === 'number') {
	                return inputString;
	            } else if (typeof inputString === 'string') {
	                var result = unformatNumbro(this, inputString);
	
	                // Any unparseable string (represented as NaN in the result) is
	                // converted into undefined.
	                return isNaN(result) ? undefined : result;
	            } else {
	                return undefined;
	            }
	        },
	
	        binaryByteUnits: function() {
	            return formatByteUnits(this._value, bytes.binary.suffixes, bytes.binary.scale).suffix;
	        },
	
	        byteUnits: function() {
	            return formatByteUnits(this._value, bytes.general.suffixes, bytes.general.scale).suffix;
	        },
	
	        decimalByteUnits: function() {
	            return formatByteUnits(this._value, bytes.decimal.suffixes, bytes.decimal.scale).suffix;
	        },
	
	        value: function() {
	            return this._value;
	        },
	
	        valueOf: function() {
	            return this._value;
	        },
	
	        set: function(value) {
	            this._value = Number(value);
	            return this;
	        },
	
	        add: function(value) {
	            var corrFactor = correctionFactor.call(null, this._value, value);
	
	            function cback(accum, curr) {
	                return accum + corrFactor * curr;
	            }
	            this._value = [this._value, value].reduce(cback, 0) / corrFactor;
	            return this;
	        },
	
	        subtract: function(value) {
	            var corrFactor = correctionFactor.call(null, this._value, value);
	
	            function cback(accum, curr) {
	                return accum - corrFactor * curr;
	            }
	            this._value = [value].reduce(cback, this._value * corrFactor) / corrFactor;
	            return this;
	        },
	
	        multiply: function(value) {
	            function cback(accum, curr) {
	                var corrFactor = correctionFactor(accum, curr),
	                    result = accum * corrFactor;
	                result *= curr * corrFactor;
	                result /= corrFactor * corrFactor;
	                return result;
	            }
	            this._value = [this._value, value].reduce(cback, 1);
	            return this;
	        },
	
	        divide: function(value) {
	            function cback(accum, curr) {
	                var corrFactor = correctionFactor(accum, curr);
	                return (accum * corrFactor) / (curr * corrFactor);
	            }
	            this._value = [this._value, value].reduce(cback);
	            return this;
	        },
	
	        difference: function(value) {
	            return Math.abs(numbro(this._value).subtract(value).value());
	        }
	
	    };
	
	    /************************************
	        Exposing Numbro
	    ************************************/
	
	    if (inNodejsRuntime()) {
	        //Todo: Rename the folder in 2.0.0
	        numbro.loadCulturesInNode();
	    }
	
	    // CommonJS module is defined
	    if (hasModule) {
	        module.exports = numbro;
	    } else {
	        /*global ender:false */
	        if (typeof ender === 'undefined') {
	            // here, `this` means `window` in the browser, or `global` on the server
	            // add `numbro` as a global object via a string identifier,
	            // for Closure Compiler 'advanced' mode
	            this.numbro = numbro;
	        }
	
	        /*global define:false */
	        if (true) {
	            !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
	                return numbro;
	            }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	        }
	    }
	
	}.call(typeof window === 'undefined' ? this : window));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(22)))

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

	/* jshint sub: true */
	exports['bg'] = __webpack_require__(353);
	exports['cs-CZ'] = __webpack_require__(354);
	exports['da-DK'] = __webpack_require__(355);
	exports['de-AT'] = __webpack_require__(356);
	exports['de-CH'] = __webpack_require__(357);
	exports['de-DE'] = __webpack_require__(358);
	exports['de-LI'] = __webpack_require__(359);
	exports['el'] = __webpack_require__(360);
	exports['en-AU'] = __webpack_require__(361);
	exports['en-GB'] = __webpack_require__(362);
	exports['en-IE'] = __webpack_require__(363);
	exports['en-NZ'] = __webpack_require__(364);
	exports['en-ZA'] = __webpack_require__(365);
	exports['es-AR'] = __webpack_require__(366);
	exports['es-CL'] = __webpack_require__(367);
	exports['es-CO'] = __webpack_require__(368);
	exports['es-CR'] = __webpack_require__(369);
	exports['es-ES'] = __webpack_require__(370);
	exports['es-NI'] = __webpack_require__(371);
	exports['es-PE'] = __webpack_require__(372);
	exports['es-PR'] = __webpack_require__(373);
	exports['es-SV'] = __webpack_require__(374);
	exports['et-EE'] = __webpack_require__(375);
	exports['fa-IR'] = __webpack_require__(376);
	exports['fi-FI'] = __webpack_require__(377);
	exports['fil-PH'] = __webpack_require__(378);
	exports['fr-CA'] = __webpack_require__(379);
	exports['fr-CH'] = __webpack_require__(380);
	exports['fr-FR'] = __webpack_require__(381);
	exports['he-IL'] = __webpack_require__(382);
	exports['hu-HU'] = __webpack_require__(383);
	exports['id'] = __webpack_require__(384);
	exports['it-CH'] = __webpack_require__(385);
	exports['it-IT'] = __webpack_require__(386);
	exports['ja-JP'] = __webpack_require__(387);
	exports['ko-KR'] = __webpack_require__(388);
	exports['lv-LV'] = __webpack_require__(389);
	exports['nb-NO'] = __webpack_require__(390);
	exports['nb'] = __webpack_require__(391);
	exports['nl-BE'] = __webpack_require__(392);
	exports['nl-NL'] = __webpack_require__(393);
	exports['nn'] = __webpack_require__(394);
	exports['pl-PL'] = __webpack_require__(395);
	exports['pt-BR'] = __webpack_require__(396);
	exports['pt-PT'] = __webpack_require__(397);
	exports['ro-RO'] = __webpack_require__(398);
	exports['ro'] = __webpack_require__(399);
	exports['ru-RU'] = __webpack_require__(400);
	exports['ru-UA'] = __webpack_require__(401);
	exports['sk-SK'] = __webpack_require__(402);
	exports['sl'] = __webpack_require__(403);
	exports['sr-Cyrl-RS'] = __webpack_require__(404);
	exports['sv-SE'] = __webpack_require__(405);
	exports['th-TH'] = __webpack_require__(406);
	exports['tr-TR'] = __webpack_require__(407);
	exports['uk-UA'] = __webpack_require__(408);
	exports['zh-CN'] = __webpack_require__(409);
	exports['zh-MO'] = __webpack_require__(410);
	exports['zh-SG'] = __webpack_require__(411);
	exports['zh-TW'] = __webpack_require__(412);

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

	/*!
	 * numbro.js language configuration
	 * language : Bulgarian
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'bg',
	        cultureCode: 'bg',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'И',
	            million: 'А',
	            billion: 'M',
	            trillion: 'T'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'лв.'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        this.numbro.culture('bg', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Czech
	 * locale: Czech Republic
	 * author : Jan Pesa : https://github.com/smajl (based on work from Anatoli Papirovski : https://github.com/apapirovski)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'cs-CZ',
	        cultureCode: 'cs-CZ',
	        delimiters: {
	            thousands: '\u00a0',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'tis.',
	            million: 'mil.',
	            billion: 'mld.',
	            trillion: 'bil.'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'Kč',
	            position: 'postfix',
	            spaceSeparated: true
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Danish
	 * locale: Denmark
	 * author : Michael Storgaard : https://github.com/mstorgaard
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'da-DK',
	        cultureCode: 'da-DK',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mio',
	            billion: 'mia',
	            trillion: 'b'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'kr',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : German
	 * locale: Austria
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'de-AT',
	        cultureCode: 'de-AT',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : German
	 * locale: Switzerland
	 * author : Michael Piefel : https://github.com/piefel (based on work from Marco Krage : https://github.com/sinky)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'de-CH',
	        cultureCode: 'de-CH',
	        delimiters: {
	            thousands: '\'',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'CHF',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : German
	 * locale: Germany
	 * author : Marco Krage : https://github.com/sinky
	 *
	 * Generally useful in Germany, Austria, Luxembourg, Belgium
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'de-DE',
	        cultureCode: 'de-DE',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix',
	            spaceSeparated: true
	        },
	        defaults: {
	            currencyFormat: ',4'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : German
	 * locale: Liechtenstein
	 * author : Michael Piefel : https://github.com/piefel (based on work from Marco Krage : https://github.com/sinky)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'de-LI',
	        cultureCode: 'de-LI',
	        delimiters: {
	            thousands: '\'',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'CHF',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Greek (el)
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'el',
	        cultureCode: 'el',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'χ',
	            million: 'ε',
	            billion: 'δ',
	            trillion: 'τ'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('el', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : English
	 * locale: Australia
	 * author : Benedikt Huss : https://github.com/ben305
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'en-AU',
	        cultureCode: 'en-AU',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (~~ (number % 100 / 10) === 1) ? 'th' :
	                (b === 1) ? 'st' :
	                (b === 2) ? 'nd' :
	                (b === 3) ? 'rd' : 'th';
	        },
	        currency: {
	            symbol: '$',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '$ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '$ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : English
	 * locale: United Kingdom of Great Britain and Northern Ireland
	 * author : Dan Ristic : https://github.com/dristic
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'en-GB',
	        cultureCode: 'en-GB',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (~~ (number % 100 / 10) === 1) ? 'th' :
	                (b === 1) ? 'st' :
	                (b === 2) ? 'nd' :
	                (b === 3) ? 'rd' : 'th';
	        },
	        currency: {
	            symbol: '£',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '$ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '$ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	+ * numbro.js language configuration
	 * language : English
	 * locale: Ireland
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'en-IE',
	        cultureCode: 'en-IE',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (~~(number % 100 / 10) === 1) ? 'th' :
	                (b === 1) ? 'st' :
	                    (b === 2) ? 'nd' :
	                        (b === 3) ? 'rd' : 'th';
	        },
	        currency: {
	            symbol: '€'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('en-gb', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : English
	 * locale: New Zealand
	 * author : Benedikt Huss : https://github.com/ben305
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'en-NZ',
	        cultureCode: 'en-NZ',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (~~ (number % 100 / 10) === 1) ? 'th' :
	                (b === 1) ? 'st' :
	                (b === 2) ? 'nd' :
	                (b === 3) ? 'rd' : 'th';
	        },
	        currency: {
	            symbol: '$',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '$ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '$ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : English
	 * locale: South Africa
	 * author : Stewart Scott https://github.com/stewart42
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'en-ZA',
	        cultureCode: 'en-ZA',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (~~ (number % 100 / 10) === 1) ? 'th' :
	                (b === 1) ? 'st' :
	                (b === 2) ? 'nd' :
	                (b === 3) ? 'rd' : 'th';
	        },
	        currency: {
	            symbol: 'R',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '$ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '$ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Argentina
	 * author : Hernan Garcia : https://github.com/hgarcia
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-AR',
	        cultureCode: 'es-AR',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                (b === 7 || b === 0) ? 'mo' :
	        (b === 8) ? 'vo' :
	        (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: '$',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Chile
	 * author : Gwyn Judd : https://github.com/gwynjudd
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-CL',
	        cultureCode: 'es-CL',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: '$',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: '$0,0'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Colombia
	 * author : Gwyn Judd : https://github.com/gwynjudd
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-CO',
	        cultureCode: 'es-CO',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Costa Rica
	 * author : Gwyn Judd : https://github.com/gwynjudd
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-CR',
	        cultureCode: 'es-CR',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: '₡',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Spain
	 * author : Hernan Garcia : https://github.com/hgarcia
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-ES',
	        cultureCode: 'es-ES',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Nicaragua
	 * author : Gwyn Judd : https://github.com/gwynjudd
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-NI',
	        cultureCode: 'es-NI',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: 'C$',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Peru
	 * author : Gwyn Judd : https://github.com/gwynjudd
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-PE',
	        cultureCode: 'es-PE',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: 'S/.',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: Puerto Rico
	 * author : Gwyn Judd : https://github.com/gwynjudd
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-PR',
	        cultureCode: 'es-PR',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: '$',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Spanish
	 * locale: El Salvador
	 * author : Gwyn Judd : https://github.com/gwynjudd
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'es-SV',
	        cultureCode: 'es-SV',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'mm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (b === 1 || b === 3) ? 'er' :
	                (b === 2) ? 'do' :
	                    (b === 7 || b === 0) ? 'mo' :
	                        (b === 8) ? 'vo' :
	                            (b === 9) ? 'no' : 'to';
	        },
	        currency: {
	            symbol: '$',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Estonian
	 * locale: Estonia
	 * author : Illimar Tambek : https://github.com/ragulka
	 *
	 * Note: in Estonian, abbreviations are always separated
	 * from numbers with a space
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'et-EE',
	        cultureCode: 'et-EE',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: ' tuh',
	            million: ' mln',
	            billion: ' mld',
	            trillion: ' trl'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Farsi
	 * locale: Iran
	 * author : neo13 : https://github.com/neo13
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'fa-IR',
	        cultureCode: 'fa-IR',
	        delimiters: {
	            thousands: '،',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'هزار',
	            million: 'میلیون',
	            billion: 'میلیارد',
	            trillion: 'تریلیون'
	        },
	        ordinal: function () {
	            return 'ام';
	        },
	        currency: {
	            symbol: '﷼'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Finnish
	 * locale: Finland
	 * author : Sami Saada : https://github.com/samitheberber
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'fi-FI',
	        cultureCode: 'fi-FI',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'M',
	            billion: 'G',
	            trillion: 'T'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Filipino (Pilipino)
	 * locale: Philippines
	 * author : Michael Abadilla : https://github.com/mjmaix
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'fil-PH',
	        cultureCode: 'fil-PH',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function (number) {
	            var b = number % 10;
	            return (~~ (number % 100 / 10) === 1) ? 'th' :
	                (b === 1) ? 'st' :
	                (b === 2) ? 'nd' :
	                (b === 3) ? 'rd' : 'th';
	        },
	        currency: {
	            symbol: '₱'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : French
	 * locale: Canada
	 * author : Léo Renaud-Allaire : https://github.com/renaudleo
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'fr-CA',
	        cultureCode: 'fr-CA',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'M',
	            billion: 'G',
	            trillion: 'T'
	        },
	        ordinal : function (number) {
	            return number === 1 ? 'er' : 'ème';
	        },
	        currency: {
	            symbol: '$',
	            position: 'postfix',
	            spaceSeparated : true
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '$ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '$ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : French
	 * locale: Switzerland
	 * author : Adam Draper : https://github.com/adamwdraper
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'fr-CH',
	        cultureCode: 'fr-CH',
	        delimiters: {
	            thousands: ' ',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal : function (number) {
	            return number === 1 ? 'er' : 'ème';
	        },
	        currency: {
	            symbol: 'CHF',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : French
	 * locale: France
	 * author : Adam Draper : https://github.com/adamwdraper
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'fr-FR',
	        cultureCode: 'fr-FR',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal : function (number) {
	            return number === 1 ? 'er' : 'ème';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Hebrew
	 * locale : IL
	 * author : Eli Zehavi : https://github.com/eli-zehavi
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'he-IL',
	        cultureCode: 'he-IL',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'אלף',
	            million: 'מליון',
	            billion: 'בליון',
	            trillion: 'טריליון'
	        },
	        currency: {
	            symbol: '₪',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '₪ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '₪ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));
	


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

	/*!
	 * numbro.js language configuration
	 * language : Hungarian
	 * locale: Hungary
	 * author : Peter Bakondy : https://github.com/pbakondy
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'hu-HU',
	        cultureCode: 'hu-HU',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'E',  // ezer
	            million: 'M',   // millió
	            billion: 'Mrd', // milliárd
	            trillion: 'T'   // trillió
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: ' Ft',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Indonesian
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'id',
	        cultureCode: 'id',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'r',
	            million: 'j',
	            billion: 'm',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'Rp'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('id', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Italian
	 * locale: Switzerland
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'it-CH',
	        cultureCode: 'it-CH',
	        delimiters: {
	            thousands: '\'',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'mila',
	            million: 'mil',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '°';
	        },
	        currency: {
	            symbol: 'CHF'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('it-CH', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Italian
	 * locale: Italy
	 * author : Giacomo Trombi : http://cinquepunti.it
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'it-IT',
	        cultureCode: 'it-IT',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'mila',
	            million: 'mil',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return 'º';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Japanese
	 * locale: Japan
	 * author : teppeis : https://github.com/teppeis
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'ja-JP',
	        cultureCode: 'ja-JP',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: '千',
	            million: '百万',
	            billion: '十億',
	            trillion: '兆'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '¥',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '$ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '$ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Korean
	 * author (numbro.js Version): Randy Wilander : https://github.com/rocketedaway
	 * author (numeral.js Version) : Rich Daley : https://github.com/pedantic-git
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'ko-KR',
	        cultureCode: 'ko-KR',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: '천',
	            million: '백만',
	            billion: '십억',
	            trillion: '일조'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '₩'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Latvian
	 * locale: Latvia
	 * author : Lauris Bukšis-Haberkorns : https://github.com/Lafriks
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'lv-LV',
	        cultureCode: 'lv-LV',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: ' tūkst.',
	            million: ' milj.',
	            billion: ' mljrd.',
	            trillion: ' trilj.'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language: Norwegian Bokmål
	 * locale: Norway
	 * author : Benjamin Van Ryseghem
	 */
	(function() {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'nb-NO',
	        cultureCode: 'nb-NO',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 't',
	            million: 'M',
	            billion: 'md',
	            trillion: 't'
	        },
	        currency: {
	            symbol: 'kr',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Norwegian Bokmål (nb)
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'nb',
	        cultureCode: 'nb',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 't',
	            million: 'mil',
	            billion: 'mia',
	            trillion: 'b'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'kr'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('nb', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Dutch
	 * locale: Belgium
	 * author : Dieter Luypaert : https://github.com/moeriki
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'nl-BE',
	        cultureCode: 'nl-BE',
	        delimiters: {
	            thousands: ' ',
	            decimal  : ','
	        },
	        abbreviations: {
	            thousand : 'k',
	            million  : 'mln',
	            billion  : 'mld',
	            trillion : 'bln'
	        },
	        ordinal : function (number) {
	            var remainder = number % 100;
	            return (number !== 0 && remainder <= 1 || remainder === 8 || remainder >= 20) ? 'ste' : 'de';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Dutch
	 * locale: Netherlands
	 * author : Dave Clayton : https://github.com/davedx
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'nl-NL',
	        cultureCode: 'nl-NL',
	        delimiters: {
	            thousands: '.',
	            decimal  : ','
	        },
	        abbreviations: {
	            thousand : 'k',
	            million  : 'mln',
	            billion  : 'mrd',
	            trillion : 'bln'
	        },
	        ordinal : function (number) {
	            var remainder = number % 100;
	            return (number !== 0 && remainder <= 1 || remainder === 8 || remainder >= 20) ? 'ste' : 'de';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Norwegian Nynorsk (nn)
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'nn',
	        cultureCode: 'nn',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 't',
	            million: 'mil',
	            billion: 'mia',
	            trillion: 'b'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'kr'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.language) {
	        window.numbro.language('nn', language);
	    }
	}());


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

	/*!
	 * numbro.js language configuration
	 * language : Polish
	 * locale : Poland
	 * author : Dominik Bulaj : https://github.com/dominikbulaj
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'pl-PL',
	        cultureCode: 'pl-PL',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'tys.',
	            million: 'mln',
	            billion: 'mld',
	            trillion: 'bln'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: ' zł',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Portuguese
	 * locale : Brazil
	 * author : Ramiro Varandas Jr : https://github.com/ramirovjr
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'pt-BR',
	        cultureCode: 'pt-BR',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'mil',
	            million: 'milhões',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return 'º';
	        },
	        currency: {
	            symbol: 'R$',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Portuguese
	 * locale : Portugal
	 * author : Diogo Resende : https://github.com/dresende
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'pt-PT',
	        cultureCode: 'pt-PT',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'k',
	            million: 'm',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal : function () {
	            return 'º';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numeral.js language configuration
	 * language : Romanian
	 * author : Andrei Alecu https://github.com/andreialecu
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'ro-RO',
	        cultureCode: 'ro-RO',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'mii',
	            million: 'mil',
	            billion: 'mld',
	            trillion: 'bln'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: ' lei',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Romanian (ro)
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'ro',
	        cultureCode: 'ro',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'mie',
	            million: 'mln',
	            billion: 'mld',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'RON'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('ro', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Russian
	 * locale : Russsia
	 * author : Anatoli Papirovski : https://github.com/apapirovski
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'ru-RU',
	        cultureCode: 'ru-RU',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'тыс.',
	            million: 'млн',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            // not ideal, but since in Russian it can taken on
	            // different forms (masculine, feminine, neuter)
	            // this is all we can do
	            return '.';
	        },
	        currency: {
	            symbol: 'руб.',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Russian
	 * locale : Ukraine
	 * author : Anatoli Papirovski : https://github.com/apapirovski
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'ru-UA',
	        cultureCode: 'ru-UA',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'тыс.',
	            million: 'млн',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            // not ideal, but since in Russian it can taken on
	            // different forms (masculine, feminine, neuter)
	            // this is all we can do
	            return '.';
	        },
	        currency: {
	            symbol: '\u20B4',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Slovak
	 * locale : Slovakia
	 * author : Jan Pesa : https://github.com/smajl (based on work from Ahmed Al Hafoudh : http://www.freevision.sk)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'sk-SK',
	        cultureCode: 'sk-SK',
	        delimiters: {
	            thousands: '\u00a0',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'tis.',
	            million: 'mil.',
	            billion: 'mld.',
	            trillion: 'bil.'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€',
	            position: 'postfix',
	            spaceSeparated: true
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Slovene
	 * locale: Slovenia
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'sl',
	        cultureCode: 'sl',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'tis.',
	            million: 'mil.',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '€'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('sl', language);
	    }
	}());


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

	/*!
	 * numbro.js language configuration
	 * language : Serbian (sr)
	 * country : Serbia (Cyrillic)
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'sr-Cyrl-RS',
	        cultureCode: 'sr-Cyrl-RS',
	        delimiters: {
	            thousands: '.',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'тыс.',
	            million: 'млн',
	            billion: 'b',
	            trillion: 't'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'RSD'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('sr-Cyrl-RS', language);
	    }
	}());


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

	/*!
	 * numbro.js language configuration
	 * language : Swedish
	 * locale : Sweden
	 * author : Benjamin Van Ryseghem (benjamin.vanryseghem.com)
	 */
	(function() {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'sv-SE',
	        cultureCode: 'sv-SE',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 't',
	            million: 'M',
	            billion: 'md',
	            trillion: 'tmd'
	        },
	        currency: {
	            symbol: 'kr',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Thai
	 * locale : Thailand
	 * author : Sathit Jittanupat : https://github.com/jojosati
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'th-TH',
	        cultureCode: 'th-TH',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: 'พัน',
	            million: 'ล้าน',
	            billion: 'พันล้าน',
	            trillion: 'ล้านล้าน'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '฿',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Turkish
	 * locale : Turkey
	 * author : Ecmel Ercan : https://github.com/ecmel,
	 *          Erhan Gundogan : https://github.com/erhangundogan,
	 *          Burak Yiğit Kaya: https://github.com/BYK
	 */
	(function() {
	    'use strict';
	
	    var suffixes = {
	            1: '\'inci',
	            5: '\'inci',
	            8: '\'inci',
	            70: '\'inci',
	            80: '\'inci',
	
	            2: '\'nci',
	            7: '\'nci',
	            20: '\'nci',
	            50: '\'nci',
	
	            3: '\'üncü',
	            4: '\'üncü',
	            100: '\'üncü',
	
	            6: '\'ncı',
	
	            9: '\'uncu',
	            10: '\'uncu',
	            30: '\'uncu',
	
	            60: '\'ıncı',
	            90: '\'ıncı'
	        },
	        language = {
	            langLocaleCode: 'tr-TR',
	            cultureCode: 'tr-TR',
	            delimiters: {
	                thousands: '.',
	                decimal: ','
	            },
	            abbreviations: {
	                thousand: 'bin',
	                million: 'milyon',
	                billion: 'milyar',
	                trillion: 'trilyon'
	            },
	            ordinal: function(number) {
	                if (number === 0) {  // special case for zero
	                    return '\'ıncı';
	                }
	
	                var a = number % 10,
	                    b = number % 100 - a,
	                    c = number >= 100 ? 100 : null;
	
	                return suffixes[a] || suffixes[b] || suffixes[c];
	            },
	            currency: {
	                symbol: '\u20BA',
	                position: 'postfix'
	            },
	            defaults: {
	                currencyFormat: ',4 a'
	            },
	            formats: {
	                fourDigits: '4 a',
	                fullWithTwoDecimals: ',0.00 $',
	                fullWithTwoDecimalsNoCurrency: ',0.00',
	                fullWithNoDecimals: ',0 $'
	            }
	        };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Ukrainian
	 * locale : Ukraine
	 * author : Michael Piefel : https://github.com/piefel (with help from Tetyana Kuzmenko)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'uk-UA',
	        cultureCode: 'uk-UA',
	        delimiters: {
	            thousands: ' ',
	            decimal: ','
	        },
	        abbreviations: {
	            thousand: 'тис.',
	            million: 'млн',
	            billion: 'млрд',
	            trillion: 'блн'
	        },
	        ordinal: function () {
	            // not ideal, but since in Ukrainian it can taken on
	            // different forms (masculine, feminine, neuter)
	            // this is all we can do
	            return '';
	        },
	        currency: {
	            symbol: '\u20B4',
	            position: 'postfix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: ',0.00 $',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: ',0 $'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : simplified chinese
	 * locale : China
	 * author : badplum : https://github.com/badplum
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'zh-CN',
	        cultureCode: 'zh-CN',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: '千',
	            million: '百万',
	            billion: '十亿',
	            trillion: '兆'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '¥',
	            position: 'prefix'
	        },
	        defaults: {
	            currencyFormat: ',4 a'
	        },
	        formats: {
	            fourDigits: '4 a',
	            fullWithTwoDecimals: '$ ,0.00',
	            fullWithTwoDecimalsNoCurrency: ',0.00',
	            fullWithNoDecimals: '$ ,0'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Chinese traditional
	 * locale: Macau
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'zh-MO',
	        cultureCode: 'zh-MO',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: '千',
	            million: '百萬',
	            billion: '十億',
	            trillion: '兆'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: 'MOP'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('zh-MO', language);
	    }
	}());


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

	/*!
	 * numbro.js language configuration
	 * language : Chinese simplified
	 * locale: Singapore
	 * author : Tim McIntosh (StayinFront NZ)
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'zh-SG',
	        cultureCode: 'zh-SG',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: '千',
	            million: '百万',
	            billion: '十亿',
	            trillion: '兆'
	        },
	        ordinal: function () {
	            return '.';
	        },
	        currency: {
	            symbol: '$'
	        }
	    };
	
	    // Node
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture('zh-SG', language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


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

	/*!
	 * numbro.js language configuration
	 * language : Chinese (Taiwan)
	 * author (numbro.js Version): Randy Wilander : https://github.com/rocketedaway
	 * author (numeral.js Version) : Rich Daley : https://github.com/pedantic-git
	 */
	(function () {
	    'use strict';
	
	    var language = {
	        langLocaleCode: 'zh-TW',
	        cultureCode: 'zh-TW',
	        delimiters: {
	            thousands: ',',
	            decimal: '.'
	        },
	        abbreviations: {
	            thousand: '千',
	            million: '百萬',
	            billion: '十億',
	            trillion: '兆'
	        },
	        ordinal: function () {
	            return '第';
	        },
	        currency: {
	            symbol: 'NT$'
	        }
	    };
	
	    // CommonJS
	    if (typeof module !== 'undefined' && module.exports) {
	        module.exports = language;
	    }
	    // Browser
	    if (typeof window !== 'undefined' && window.numbro && window.numbro.culture) {
	        window.numbro.culture(language.cultureCode, language);
	    }
	}.call(typeof window === 'undefined' ? this : window));


/***/ }),
/* 413 */
/***/ (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__(414); } catch (e) {}
	        module.exports = factory(moment);
	    } else if (typeof define === 'function' && define.amd) {
	        // AMD. Register as an anonymous module.
	        define(function (req)
	        {
	            // Load moment.js as an optional dependency
	            var id = 'moment';
	            try { moment = req(id); } catch (e) {}
	            return factory(moment);
	        });
	    } else {
	        root.Pikaday = factory(root.moment);
	    }
	}(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;
	
	}));


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

	/* WEBPACK VAR INJECTION */(function(module) {//! moment.js
	//! version : 2.17.1
	//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
	//! license : MIT
	//! momentjs.com
	
	;(function (global, factory) {
	     true ? module.exports = factory() :
	    typeof define === 'function' && define.amd ? define(factory) :
	    global.moment = factory()
	}(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) {
	    var k;
	    for (k in obj) {
	        // even if its not own property I'd still call it non-empty
	        return false;
	    }
	    return true;
	}
	
	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
	    };
	}
	
	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;
	    };
	}
	
	var some$1 = some;
	
	function isValid(m) {
	    if (m._isValid == null) {
	        var flags = getParsingFlags(m);
	        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {
	            return i != null;
	        });
	        var isNowValid = !isNaN(m._d.getTime()) &&
	            flags.overflow < 0 &&
	            !flags.empty &&
	            !flags.invalidMonth &&
	            !flags.invalidWeekday &&
	            !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;
	}
	
	function isUndefined(input) {
	    return input === void 0;
	}
	
	// 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 in momentProperties) {
	            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 _ordinalParseLenient.
	    this._ordinalParseLenient = new RegExp(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 keys$1 = keys;
	
	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 defaultOrdinalParse = /\d{1,2}/;
	
	function ordinal (number) {
	    return this._ordinal.replace('%d', number);
	}
	
	var defaultRelativeTime = {
	    future : 'in %s',
	    past   : '%s ago',
	    s  : 'a few 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 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()) {
	        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 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 += array[i] instanceof Function ? 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]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){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;
	
	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;
	    };
	}
	
	var indexOf$1 = indexOf;
	
	function daysInMonth(year, month) {
	    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
	}
	
	// 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 this._months;
	    }
	    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 this._monthsShort;
	    }
	    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$1.call(this._shortMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    } else {
	        if (format === 'MMM') {
	            ii = indexOf$1.call(this._shortMonthsParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.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');
	}
	
	// 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 createDate (y, m, d, h, M, s, ms) {
	    //can't just apply() to create a date:
	    //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
	    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;
	}
	
	//http://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 this._weekdays;
	    }
	    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$1.call(this._weekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else if (format === 'ddd') {
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    } else {
	        if (format === 'dddd') {
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else if (format === 'ddd') {
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.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('HH', match1to2, match2);
	addRegexToken('hh', match1to2, match2);
	
	addRegexToken('hmm', match3to4);
	addRegexToken('hmmss', match5to6);
	addRegexToken('Hmm', match3to4);
	addRegexToken('Hmmss', match5to6);
	
	addParseToken(['H', 'HH'], HOUR);
	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,
	    ordinalParse: defaultOrdinalParse,
	    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;
	            __webpack_require__(415)("./" + name);
	            // because defineLocale currently also sets the global locale, we
	            // want to undo that for lazy loaded locales
	            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, parentConfig = baseConfig;
	        // MERGE
	        if (locales[name] != null) {
	            parentConfig = locales[name]._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$1(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;
	}
	
	// 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;
	    }
	}
	
	// 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;
	        hooks.createFromInputFallback(config);
	    }
	}
	
	hooks.createFromInputFallback = deprecate(
	    'value provided is not in a recognized ISO format. moment construction falls back to js Date(), ' +
	    'which is not reliable across all browsers and versions. Non 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' : ''));
	    }
	);
	
	// 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, 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) {
	        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
	
	        if (config._dayOfYear > daysInYear(yearToUse)) {
	            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);
	    // 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;
	    }
	}
	
	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;
	    }
	}
	
	// constant that refers to the ISO standard
	hooks.ISO_8601 = 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;
	    }
	
	    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 (input === undefined) {
	        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 (typeof(input) === 'object') {
	        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());
	};
	
	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;
	
	    // 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 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) {
	    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) {
	            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);
	    } 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;
	
	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 (milliseconds) {
	        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
	    }
	    if (days) {
	        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
	    }
	    if (months) {
	        setMonth(mom, get(mom, 'Month') + months * 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);
	
	    if (units === 'year' || units === 'month' || units === 'quarter') {
	        output = monthDiff(this, that);
	        if (units === 'quarter') {
	            output = output / 3;
	        } else if (units === 'year') {
	            output = output / 12;
	        }
	    } else {
	        delta = this - that;
	        output = units === 'second' ? delta / 1e3 : // 1000
	            units === 'minute' ? delta / 6e4 : // 1000 * 60
	            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
	            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
	            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
	            delta;
	    }
	    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 () {
	    var m = this.clone().utc();
	    if (0 < m.year() && m.year() <= 9999) {
	        if (isFunction(Date.prototype.toISOString)) {
	            // native implementation is ~50x faster, use it when we can
	            return this.toDate().toISOString();
	        } else {
	            return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	        }
	    } else {
	        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	    }
	}
	
	/**
	 * 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$1 () {
	    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) {
	    return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
	});
	
	addParseToken(['D', 'DD'], DATE);
	addParseToken('Do', function (input, array) {
	    array[DATE] = toInt(input.match(match1to2)[0], 10);
	});
	
	// 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$1;
	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', {
	    ordinalParse: /\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) {
	    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 () {
	    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 get$2 (units) {
	    units = normalizeUnits(units);
	    return this[units + 's']();
	}
	
	function makeGetter(name) {
	    return function () {
	        return this._data[name];
	    };
	}
	
	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 = {
	    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.s && ['s', 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;
	    return true;
	}
	
	function humanize (withSuffix) {
	    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 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)
	    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;
	    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';
	    }
	
	    return (total < 0 ? '-' : '') +
	        'P' +
	        (Y ? Y + 'Y' : '') +
	        (M ? M + 'M' : '') +
	        (D ? D + 'D' : '') +
	        ((h || m || s) ? 'T' : '') +
	        (h ? h + 'H' : '') +
	        (m ? m + 'M' : '') +
	        (s ? s + 'S' : '');
	}
	
	var proto$2 = Duration.prototype;
	
	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.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.17.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;
	
	return hooks;
	
	})));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(145)(module)))

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

	var map = {
		"./af": 416,
		"./af.js": 416,
		"./ar": 417,
		"./ar-dz": 418,
		"./ar-dz.js": 418,
		"./ar-ly": 419,
		"./ar-ly.js": 419,
		"./ar-ma": 420,
		"./ar-ma.js": 420,
		"./ar-sa": 421,
		"./ar-sa.js": 421,
		"./ar-tn": 422,
		"./ar-tn.js": 422,
		"./ar.js": 417,
		"./az": 423,
		"./az.js": 423,
		"./be": 424,
		"./be.js": 424,
		"./bg": 425,
		"./bg.js": 425,
		"./bn": 426,
		"./bn.js": 426,
		"./bo": 427,
		"./bo.js": 427,
		"./br": 428,
		"./br.js": 428,
		"./bs": 429,
		"./bs.js": 429,
		"./ca": 430,
		"./ca.js": 430,
		"./cs": 431,
		"./cs.js": 431,
		"./cv": 432,
		"./cv.js": 432,
		"./cy": 433,
		"./cy.js": 433,
		"./da": 434,
		"./da.js": 434,
		"./de": 435,
		"./de-at": 436,
		"./de-at.js": 436,
		"./de.js": 435,
		"./dv": 437,
		"./dv.js": 437,
		"./el": 438,
		"./el.js": 438,
		"./en-au": 439,
		"./en-au.js": 439,
		"./en-ca": 440,
		"./en-ca.js": 440,
		"./en-gb": 441,
		"./en-gb.js": 441,
		"./en-ie": 442,
		"./en-ie.js": 442,
		"./en-nz": 443,
		"./en-nz.js": 443,
		"./eo": 444,
		"./eo.js": 444,
		"./es": 445,
		"./es-do": 446,
		"./es-do.js": 446,
		"./es.js": 445,
		"./et": 447,
		"./et.js": 447,
		"./eu": 448,
		"./eu.js": 448,
		"./fa": 449,
		"./fa.js": 449,
		"./fi": 450,
		"./fi.js": 450,
		"./fo": 451,
		"./fo.js": 451,
		"./fr": 452,
		"./fr-ca": 453,
		"./fr-ca.js": 453,
		"./fr-ch": 454,
		"./fr-ch.js": 454,
		"./fr.js": 452,
		"./fy": 455,
		"./fy.js": 455,
		"./gd": 456,
		"./gd.js": 456,
		"./gl": 457,
		"./gl.js": 457,
		"./he": 458,
		"./he.js": 458,
		"./hi": 459,
		"./hi.js": 459,
		"./hr": 460,
		"./hr.js": 460,
		"./hu": 461,
		"./hu.js": 461,
		"./hy-am": 462,
		"./hy-am.js": 462,
		"./id": 463,
		"./id.js": 463,
		"./is": 464,
		"./is.js": 464,
		"./it": 465,
		"./it.js": 465,
		"./ja": 466,
		"./ja.js": 466,
		"./jv": 467,
		"./jv.js": 467,
		"./ka": 468,
		"./ka.js": 468,
		"./kk": 469,
		"./kk.js": 469,
		"./km": 470,
		"./km.js": 470,
		"./ko": 471,
		"./ko.js": 471,
		"./ky": 472,
		"./ky.js": 472,
		"./lb": 473,
		"./lb.js": 473,
		"./lo": 474,
		"./lo.js": 474,
		"./lt": 475,
		"./lt.js": 475,
		"./lv": 476,
		"./lv.js": 476,
		"./me": 477,
		"./me.js": 477,
		"./mi": 478,
		"./mi.js": 478,
		"./mk": 479,
		"./mk.js": 479,
		"./ml": 480,
		"./ml.js": 480,
		"./mr": 481,
		"./mr.js": 481,
		"./ms": 482,
		"./ms-my": 483,
		"./ms-my.js": 483,
		"./ms.js": 482,
		"./my": 484,
		"./my.js": 484,
		"./nb": 485,
		"./nb.js": 485,
		"./ne": 486,
		"./ne.js": 486,
		"./nl": 487,
		"./nl-be": 488,
		"./nl-be.js": 488,
		"./nl.js": 487,
		"./nn": 489,
		"./nn.js": 489,
		"./pa-in": 490,
		"./pa-in.js": 490,
		"./pl": 491,
		"./pl.js": 491,
		"./pt": 492,
		"./pt-br": 493,
		"./pt-br.js": 493,
		"./pt.js": 492,
		"./ro": 494,
		"./ro.js": 494,
		"./ru": 495,
		"./ru.js": 495,
		"./se": 496,
		"./se.js": 496,
		"./si": 497,
		"./si.js": 497,
		"./sk": 498,
		"./sk.js": 498,
		"./sl": 499,
		"./sl.js": 499,
		"./sq": 500,
		"./sq.js": 500,
		"./sr": 501,
		"./sr-cyrl": 502,
		"./sr-cyrl.js": 502,
		"./sr.js": 501,
		"./ss": 503,
		"./ss.js": 503,
		"./sv": 504,
		"./sv.js": 504,
		"./sw": 505,
		"./sw.js": 505,
		"./ta": 506,
		"./ta.js": 506,
		"./te": 507,
		"./te.js": 507,
		"./tet": 508,
		"./tet.js": 508,
		"./th": 509,
		"./th.js": 509,
		"./tl-ph": 510,
		"./tl-ph.js": 510,
		"./tlh": 511,
		"./tlh.js": 511,
		"./tr": 512,
		"./tr.js": 512,
		"./tzl": 513,
		"./tzl.js": 513,
		"./tzm": 514,
		"./tzm-latn": 515,
		"./tzm-latn.js": 515,
		"./tzm.js": 514,
		"./uk": 516,
		"./uk.js": 516,
		"./uz": 517,
		"./uz.js": 517,
		"./vi": 518,
		"./vi.js": 518,
		"./x-pseudo": 519,
		"./x-pseudo.js": 519,
		"./yo": 520,
		"./yo.js": 520,
		"./zh-cn": 521,
		"./zh-cn.js": 521,
		"./zh-hk": 522,
		"./zh-hk.js": 522,
		"./zh-tw": 523,
		"./zh-tw.js": 523
	};
	function webpackContext(req) {
		return __webpack_require__(webpackContextResolve(req));
	};
	function webpackContextResolve(req) {
		return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
	};
	webpackContext.keys = function webpackContextKeys() {
		return Object.keys(map);
	};
	webpackContext.resolve = webpackContextResolve;
	module.exports = webpackContext;
	webpackContext.id = 415;


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

	//! moment.js locale configuration
	//! locale : Afrikaans [af]
	//! author : Werner Mollentze : https://github.com/wernerm
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var af = moment.defineLocale('af', {
	    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),
	    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
	    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
	    meridiemParse: /vm|nm/i,
	    isPM : function (input) {
	        return /^nm$/i.test(input);
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower ? 'vm' : 'VM';
	        } else {
	            return isLower ? 'nm' : 'NM';
	        }
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Vandag om] LT',
	        nextDay : '[Môre om] LT',
	        nextWeek : 'dddd [om] LT',
	        lastDay : '[Gister om] LT',
	        lastWeek : '[Laas] dddd [om] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'oor %s',
	        past : '%s gelede',
	        s : '\'n paar sekondes',
	        m : '\'n minuut',
	        mm : '%d minute',
	        h : '\'n uur',
	        hh : '%d ure',
	        d : '\'n dag',
	        dd : '%d dae',
	        M : '\'n maand',
	        MM : '%d maande',
	        y : '\'n jaar',
	        yy : '%d jaar'
	    },
	    ordinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter
	    },
	    week : {
	        dow : 1, // Maandag is die eerste dag van die week.
	        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
	    }
	});
	
	return af;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic [ar]
	//! author : Abdel Said: https://github.com/abdelsaid
	//! author : Ahmed Elkhatib
	//! author : forabi https://github.com/forabi
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '١',
	    '2': '٢',
	    '3': '٣',
	    '4': '٤',
	    '5': '٥',
	    '6': '٦',
	    '7': '٧',
	    '8': '٨',
	    '9': '٩',
	    '0': '٠'
	};
	var numberMap = {
	    '١': '1',
	    '٢': '2',
	    '٣': '3',
	    '٤': '4',
	    '٥': '5',
	    '٦': '6',
	    '٧': '7',
	    '٨': '8',
	    '٩': '9',
	    '٠': '0'
	};
	var pluralForm = function (n) {
	    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
	};
	var plurals = {
	    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
	    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
	    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
	    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
	    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
	    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
	};
	var pluralize = function (u) {
	    return function (number, withoutSuffix, string, isFuture) {
	        var f = pluralForm(number),
	            str = plurals[u][pluralForm(number)];
	        if (f === 2) {
	            str = str[withoutSuffix ? 0 : 1];
	        }
	        return str.replace(/%d/i, number);
	    };
	};
	var months = [
	    'كانون الثاني يناير',
	    'شباط فبراير',
	    'آذار مارس',
	    'نيسان أبريل',
	    'أيار مايو',
	    'حزيران يونيو',
	    'تموز يوليو',
	    'آب أغسطس',
	    'أيلول سبتمبر',
	    'تشرين الأول أكتوبر',
	    'تشرين الثاني نوفمبر',
	    'كانون الأول ديسمبر'
	];
	
	var ar = moment.defineLocale('ar', {
	    months : months,
	    monthsShort : months,
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/\u200FM/\u200FYYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم عند الساعة] LT',
	        nextDay: '[غدًا عند الساعة] LT',
	        nextWeek: 'dddd [عند الساعة] LT',
	        lastDay: '[أمس عند الساعة] LT',
	        lastWeek: 'dddd [عند الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'بعد %s',
	        past : 'منذ %s',
	        s : pluralize('s'),
	        m : pluralize('m'),
	        mm : pluralize('m'),
	        h : pluralize('h'),
	        hh : pluralize('h'),
	        d : pluralize('d'),
	        dd : pluralize('d'),
	        M : pluralize('M'),
	        MM : pluralize('M'),
	        y : pluralize('y'),
	        yy : pluralize('y')
	    },
	    preparse: function (string) {
	        return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ar;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Algeria) [ar-dz]
	//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arDz = moment.defineLocale('ar-dz', {
	    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 4  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arDz;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Lybia) [ar-ly]
	//! author : Ali Hmer: https://github.com/kikoanis
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '1',
	    '2': '2',
	    '3': '3',
	    '4': '4',
	    '5': '5',
	    '6': '6',
	    '7': '7',
	    '8': '8',
	    '9': '9',
	    '0': '0'
	};
	var pluralForm = function (n) {
	    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
	};
	var plurals = {
	    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
	    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
	    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
	    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
	    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
	    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
	};
	var pluralize = function (u) {
	    return function (number, withoutSuffix, string, isFuture) {
	        var f = pluralForm(number),
	            str = plurals[u][pluralForm(number)];
	        if (f === 2) {
	            str = str[withoutSuffix ? 0 : 1];
	        }
	        return str.replace(/%d/i, number);
	    };
	};
	var months = [
	    'يناير',
	    'فبراير',
	    'مارس',
	    'أبريل',
	    'مايو',
	    'يونيو',
	    'يوليو',
	    'أغسطس',
	    'سبتمبر',
	    'أكتوبر',
	    'نوفمبر',
	    'ديسمبر'
	];
	
	var arLy = moment.defineLocale('ar-ly', {
	    months : months,
	    monthsShort : months,
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/\u200FM/\u200FYYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم عند الساعة] LT',
	        nextDay: '[غدًا عند الساعة] LT',
	        nextWeek: 'dddd [عند الساعة] LT',
	        lastDay: '[أمس عند الساعة] LT',
	        lastWeek: 'dddd [عند الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'بعد %s',
	        past : 'منذ %s',
	        s : pluralize('s'),
	        m : pluralize('m'),
	        mm : pluralize('m'),
	        h : pluralize('h'),
	        hh : pluralize('h'),
	        d : pluralize('d'),
	        dd : pluralize('d'),
	        M : pluralize('M'),
	        MM : pluralize('M'),
	        y : pluralize('y'),
	        yy : pluralize('y')
	    },
	    preparse: function (string) {
	        return string.replace(/\u200f/g, '').replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arLy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Morocco) [ar-ma]
	//! author : ElFadili Yassine : https://github.com/ElFadiliY
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arMa = moment.defineLocale('ar-ma', {
	    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arMa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Arabic (Saudi Arabia) [ar-sa]
	//! author : Suhail Alkowaileet : https://github.com/xsoh
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '١',
	    '2': '٢',
	    '3': '٣',
	    '4': '٤',
	    '5': '٥',
	    '6': '٦',
	    '7': '٧',
	    '8': '٨',
	    '9': '٩',
	    '0': '٠'
	};
	var numberMap = {
	    '١': '1',
	    '٢': '2',
	    '٣': '3',
	    '٤': '4',
	    '٥': '5',
	    '٦': '6',
	    '٧': '7',
	    '٨': '8',
	    '٩': '9',
	    '٠': '0'
	};
	
	var arSa = moment.defineLocale('ar-sa', {
	    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    preparse: function (string) {
	        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        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.
	    }
	});
	
	return arSa;
	
	})));


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

	//! moment.js locale configuration
	//! locale  :  Arabic (Tunisia) [ar-tn]
	//! author : Nader Toukabri : https://github.com/naderio
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arTn = moment.defineLocale('ar-tn', {
	    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'في %s',
	        past: 'منذ %s',
	        s: 'ثوان',
	        m: 'دقيقة',
	        mm: '%d دقائق',
	        h: 'ساعة',
	        hh: '%d ساعات',
	        d: 'يوم',
	        dd: '%d أيام',
	        M: 'شهر',
	        MM: '%d أشهر',
	        y: 'سنة',
	        yy: '%d سنوات'
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return arTn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Azerbaijani [az]
	//! author : topchiyev : https://github.com/topchiyev
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    1: '-inci',
	    5: '-inci',
	    8: '-inci',
	    70: '-inci',
	    80: '-inci',
	    2: '-nci',
	    7: '-nci',
	    20: '-nci',
	    50: '-nci',
	    3: '-üncü',
	    4: '-üncü',
	    100: '-üncü',
	    6: '-ncı',
	    9: '-uncu',
	    10: '-uncu',
	    30: '-uncu',
	    60: '-ıncı',
	    90: '-ıncı'
	};
	
	var az = moment.defineLocale('az', {
	    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),
	    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
	    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),
	    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
	    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[bugün saat] LT',
	        nextDay : '[sabah saat] LT',
	        nextWeek : '[gələn həftə] dddd [saat] LT',
	        lastDay : '[dünən] LT',
	        lastWeek : '[keçən həftə] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s sonra',
	        past : '%s əvvəl',
	        s : 'birneçə saniyyə',
	        m : 'bir dəqiqə',
	        mm : '%d dəqiqə',
	        h : 'bir saat',
	        hh : '%d saat',
	        d : 'bir gün',
	        dd : '%d gün',
	        M : 'bir ay',
	        MM : '%d ay',
	        y : 'bir il',
	        yy : '%d il'
	    },
	    meridiemParse: /gecə|səhər|gündüz|axşam/,
	    isPM : function (input) {
	        return /^(gündüz|axşam)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'gecə';
	        } else if (hour < 12) {
	            return 'səhər';
	        } else if (hour < 17) {
	            return 'gündüz';
	        } else {
	            return 'axşam';
	        }
	    },
	    ordinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
	    ordinal : function (number) {
	        if (number === 0) {  // special case for zero
	            return number + '-ıncı';
	        }
	        var a = number % 10,
	            b = number % 100 - a,
	            c = number >= 100 ? 100 : null;
	        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return az;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Belarusian [be]
	//! author : Dmitry Demidov : https://github.com/demidov91
	//! author: Praleska: http://praleska.pro/
	//! Author : Menelion Elensúle : https://github.com/Oire
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
	        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
	        'dd': 'дзень_дні_дзён',
	        'MM': 'месяц_месяцы_месяцаў',
	        'yy': 'год_гады_гадоў'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'хвіліна' : 'хвіліну';
	    }
	    else if (key === 'h') {
	        return withoutSuffix ? 'гадзіна' : 'гадзіну';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	
	var be = moment.defineLocale('be', {
	    months : {
	        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),
	        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')
	    },
	    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),
	    weekdays : {
	        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),
	        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),
	        isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/
	    },
	    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
	    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY г.',
	        LLL : 'D MMMM YYYY г., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY г., HH:mm'
	    },
	    calendar : {
	        sameDay: '[Сёння ў] LT',
	        nextDay: '[Заўтра ў] LT',
	        lastDay: '[Учора ў] LT',
	        nextWeek: function () {
	            return '[У] dddd [ў] LT';
	        },
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 5:
	                case 6:
	                    return '[У мінулую] dddd [ў] LT';
	                case 1:
	                case 2:
	                case 4:
	                    return '[У мінулы] dddd [ў] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'праз %s',
	        past : '%s таму',
	        s : 'некалькі секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : relativeTimeWithPlural,
	        hh : relativeTimeWithPlural,
	        d : 'дзень',
	        dd : relativeTimeWithPlural,
	        M : 'месяц',
	        MM : relativeTimeWithPlural,
	        y : 'год',
	        yy : relativeTimeWithPlural
	    },
	    meridiemParse: /ночы|раніцы|дня|вечара/,
	    isPM : function (input) {
	        return /^(дня|вечара)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночы';
	        } else if (hour < 12) {
	            return 'раніцы';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечара';
	        }
	    },
	    ordinalParse: /\d{1,2}-(і|ы|га)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	            case 'w':
	            case 'W':
	                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';
	            case 'D':
	                return number + '-га';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return be;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Bulgarian [bg]
	//! author : Krasen Borisov : https://github.com/kraz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var bg = moment.defineLocale('bg', {
	    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
	    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
	    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),
	    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
	    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'D.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay : '[Днес в] LT',
	        nextDay : '[Утре в] LT',
	        nextWeek : 'dddd [в] LT',
	        lastDay : '[Вчера в] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 6:
	                    return '[В изминалата] dddd [в] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[В изминалия] dddd [в] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'след %s',
	        past : 'преди %s',
	        s : 'няколко секунди',
	        m : 'минута',
	        mm : '%d минути',
	        h : 'час',
	        hh : '%d часа',
	        d : 'ден',
	        dd : '%d дни',
	        M : 'месец',
	        MM : '%d месеца',
	        y : 'година',
	        yy : '%d години'
	    },
	    ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
	    ordinal : function (number) {
	        var lastDigit = number % 10,
	            last2Digits = number % 100;
	        if (number === 0) {
	            return number + '-ев';
	        } else if (last2Digits === 0) {
	            return number + '-ен';
	        } else if (last2Digits > 10 && last2Digits < 20) {
	            return number + '-ти';
	        } else if (lastDigit === 1) {
	            return number + '-ви';
	        } else if (lastDigit === 2) {
	            return number + '-ри';
	        } else if (lastDigit === 7 || lastDigit === 8) {
	            return number + '-ми';
	        } else {
	            return number + '-ти';
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bg;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Bengali [bn]
	//! author : Kaushik Gandhi : https://github.com/kaushikgandhi
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '১',
	    '2': '২',
	    '3': '৩',
	    '4': '৪',
	    '5': '৫',
	    '6': '৬',
	    '7': '৭',
	    '8': '৮',
	    '9': '৯',
	    '0': '০'
	};
	var numberMap = {
	    '১': '1',
	    '২': '2',
	    '৩': '3',
	    '৪': '4',
	    '৫': '5',
	    '৬': '6',
	    '৭': '7',
	    '৮': '8',
	    '৯': '9',
	    '০': '0'
	};
	
	var bn = moment.defineLocale('bn', {
	    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),
	    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),
	    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),
	    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
	    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm সময়',
	        LTS : 'A h:mm:ss সময়',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm সময়',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
	    },
	    calendar : {
	        sameDay : '[আজ] LT',
	        nextDay : '[আগামীকাল] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[গতকাল] LT',
	        lastWeek : '[গত] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s পরে',
	        past : '%s আগে',
	        s : 'কয়েক সেকেন্ড',
	        m : 'এক মিনিট',
	        mm : '%d মিনিট',
	        h : 'এক ঘন্টা',
	        hh : '%d ঘন্টা',
	        d : 'এক দিন',
	        dd : '%d দিন',
	        M : 'এক মাস',
	        MM : '%d মাস',
	        y : 'এক বছর',
	        yy : '%d বছর'
	    },
	    preparse: function (string) {
	        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'রাত' && hour >= 4) ||
	                (meridiem === 'দুপুর' && hour < 5) ||
	                meridiem === 'বিকাল') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'রাত';
	        } else if (hour < 10) {
	            return 'সকাল';
	        } else if (hour < 17) {
	            return 'দুপুর';
	        } else if (hour < 20) {
	            return 'বিকাল';
	        } else {
	            return 'রাত';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return bn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tibetan [bo]
	//! author : Thupten N. Chakrishar : https://github.com/vajradog
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '༡',
	    '2': '༢',
	    '3': '༣',
	    '4': '༤',
	    '5': '༥',
	    '6': '༦',
	    '7': '༧',
	    '8': '༨',
	    '9': '༩',
	    '0': '༠'
	};
	var numberMap = {
	    '༡': '1',
	    '༢': '2',
	    '༣': '3',
	    '༤': '4',
	    '༥': '5',
	    '༦': '6',
	    '༧': '7',
	    '༨': '8',
	    '༩': '9',
	    '༠': '0'
	};
	
	var bo = moment.defineLocale('bo', {
	    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
	    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
	    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),
	    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
	    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[དི་རིང] LT',
	        nextDay : '[སང་ཉིན] LT',
	        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',
	        lastDay : '[ཁ་སང] LT',
	        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ལ་',
	        past : '%s སྔན་ལ',
	        s : 'ལམ་སང',
	        m : 'སྐར་མ་གཅིག',
	        mm : '%d སྐར་མ',
	        h : 'ཆུ་ཚོད་གཅིག',
	        hh : '%d ཆུ་ཚོད',
	        d : 'ཉིན་གཅིག',
	        dd : '%d ཉིན་',
	        M : 'ཟླ་བ་གཅིག',
	        MM : '%d ཟླ་བ',
	        y : 'ལོ་གཅིག',
	        yy : '%d ལོ'
	    },
	    preparse: function (string) {
	        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||
	                (meridiem === 'ཉིན་གུང' && hour < 5) ||
	                meridiem === 'དགོང་དག') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'མཚན་མོ';
	        } else if (hour < 10) {
	            return 'ཞོགས་ཀས';
	        } else if (hour < 17) {
	            return 'ཉིན་གུང';
	        } else if (hour < 20) {
	            return 'དགོང་དག';
	        } else {
	            return 'མཚན་མོ';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return bo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Breton [br]
	//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function relativeTimeWithMutation(number, withoutSuffix, key) {
	    var format = {
	        'mm': 'munutenn',
	        'MM': 'miz',
	        'dd': 'devezh'
	    };
	    return number + ' ' + mutation(format[key], number);
	}
	function specialMutationForYears(number) {
	    switch (lastNumber(number)) {
	        case 1:
	        case 3:
	        case 4:
	        case 5:
	        case 9:
	            return number + ' bloaz';
	        default:
	            return number + ' vloaz';
	    }
	}
	function lastNumber(number) {
	    if (number > 9) {
	        return lastNumber(number % 10);
	    }
	    return number;
	}
	function mutation(text, number) {
	    if (number === 2) {
	        return softMutation(text);
	    }
	    return text;
	}
	function softMutation(text) {
	    var mutationTable = {
	        'm': 'v',
	        'b': 'v',
	        'd': 'z'
	    };
	    if (mutationTable[text.charAt(0)] === undefined) {
	        return text;
	    }
	    return mutationTable[text.charAt(0)] + text.substring(1);
	}
	
	var br = moment.defineLocale('br', {
	    months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),
	    monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
	    weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'),
	    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
	    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h[e]mm A',
	        LTS : 'h[e]mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D [a viz] MMMM YYYY',
	        LLL : 'D [a viz] MMMM YYYY h[e]mm A',
	        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
	    },
	    calendar : {
	        sameDay : '[Hiziv da] LT',
	        nextDay : '[Warc\'hoazh da] LT',
	        nextWeek : 'dddd [da] LT',
	        lastDay : '[Dec\'h da] LT',
	        lastWeek : 'dddd [paset da] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'a-benn %s',
	        past : '%s \'zo',
	        s : 'un nebeud segondennoù',
	        m : 'ur vunutenn',
	        mm : relativeTimeWithMutation,
	        h : 'un eur',
	        hh : '%d eur',
	        d : 'un devezh',
	        dd : relativeTimeWithMutation,
	        M : 'ur miz',
	        MM : relativeTimeWithMutation,
	        y : 'ur bloaz',
	        yy : specialMutationForYears
	    },
	    ordinalParse: /\d{1,2}(añ|vet)/,
	    ordinal : function (number) {
	        var output = (number === 1) ? 'añ' : 'vet';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return br;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Bosnian [bs]
	//! author : Nedim Cholich : https://github.com/frontyard
	//! based on (hr) translation by Bojan Marković
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
	        case 'mm':
	            if (number === 1) {
	                result += 'minuta';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'minute';
	            } else {
	                result += 'minuta';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'jedan sat' : 'jednog sata';
	        case 'hh':
	            if (number === 1) {
	                result += 'sat';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'sata';
	            } else {
	                result += 'sati';
	            }
	            return result;
	        case 'dd':
	            if (number === 1) {
	                result += 'dan';
	            } else {
	                result += 'dana';
	            }
	            return result;
	        case 'MM':
	            if (number === 1) {
	                result += 'mjesec';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'mjeseca';
	            } else {
	                result += 'mjeseci';
	            }
	            return result;
	        case 'yy':
	            if (number === 1) {
	                result += 'godina';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'godine';
	            } else {
	                result += 'godina';
	            }
	            return result;
	    }
	}
	
	var bs = moment.defineLocale('bs', {
	    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danas u] LT',
	        nextDay  : '[sutra u] LT',
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[jučer u] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                    return '[prošlu] dddd [u] LT';
	                case 6:
	                    return '[prošle] [subote] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prošli] dddd [u] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'par sekundi',
	        m      : translate,
	        mm     : translate,
	        h      : translate,
	        hh     : translate,
	        d      : 'dan',
	        dd     : translate,
	        M      : 'mjesec',
	        MM     : translate,
	        y      : 'godinu',
	        yy     : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bs;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Catalan [ca]
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ca = moment.defineLocale('ca', {
	    months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
	    monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),
	    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
	    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        nextDay : function () {
	            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        lastDay : function () {
	            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'd\'aquí %s',
	        past : 'fa %s',
	        s : 'uns segons',
	        m : 'un minut',
	        mm : '%d minuts',
	        h : 'una hora',
	        hh : '%d hores',
	        d : 'un dia',
	        dd : '%d dies',
	        M : 'un mes',
	        MM : '%d mesos',
	        y : 'un any',
	        yy : '%d anys'
	    },
	    ordinalParse: /\d{1,2}(r|n|t|è|a)/,
	    ordinal : function (number, period) {
	        var output = (number === 1) ? 'r' :
	            (number === 2) ? 'n' :
	            (number === 3) ? 'r' :
	            (number === 4) ? 't' : 'è';
	        if (period === 'w' || period === 'W') {
	            output = 'a';
	        }
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ca;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Czech [cs]
	//! author : petrbela : https://github.com/petrbela
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');
	var monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');
	function plural(n) {
	    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':  // a few seconds / in a few seconds / a few seconds ago
	            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
	        case 'm':  // a minute / in a minute / a minute ago
	            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
	        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'minuty' : 'minut');
	            } else {
	                return result + 'minutami';
	            }
	            break;
	        case 'h':  // an hour / in an hour / an hour ago
	            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
	        case 'hh': // 9 hours / in 9 hours / 9 hours ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'hodiny' : 'hodin');
	            } else {
	                return result + 'hodinami';
	            }
	            break;
	        case 'd':  // a day / in a day / a day ago
	            return (withoutSuffix || isFuture) ? 'den' : 'dnem';
	        case 'dd': // 9 days / in 9 days / 9 days ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'dny' : 'dní');
	            } else {
	                return result + 'dny';
	            }
	            break;
	        case 'M':  // a month / in a month / a month ago
	            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
	        case 'MM': // 9 months / in 9 months / 9 months ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'měsíce' : 'měsíců');
	            } else {
	                return result + 'měsíci';
	            }
	            break;
	        case 'y':  // a year / in a year / a year ago
	            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
	        case 'yy': // 9 years / in 9 years / 9 years ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'roky' : 'let');
	            } else {
	                return result + 'lety';
	            }
	            break;
	    }
	}
	
	var cs = moment.defineLocale('cs', {
	    months : months,
	    monthsShort : monthsShort,
	    monthsParse : (function (months, monthsShort) {
	        var i, _monthsParse = [];
	        for (i = 0; i < 12; i++) {
	            // use custom parser to solve problem with July (červenec)
	            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
	        }
	        return _monthsParse;
	    }(months, monthsShort)),
	    shortMonthsParse : (function (monthsShort) {
	        var i, _shortMonthsParse = [];
	        for (i = 0; i < 12; i++) {
	            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');
	        }
	        return _shortMonthsParse;
	    }(monthsShort)),
	    longMonthsParse : (function (months) {
	        var i, _longMonthsParse = [];
	        for (i = 0; i < 12; i++) {
	            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');
	        }
	        return _longMonthsParse;
	    }(months)),
	    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
	    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),
	    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
	    longDateFormat : {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd D. MMMM YYYY H:mm',
	        l : 'D. M. YYYY'
	    },
	    calendar : {
	        sameDay: '[dnes v] LT',
	        nextDay: '[zítra v] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v neděli v] LT';
	                case 1:
	                case 2:
	                    return '[v] dddd [v] LT';
	                case 3:
	                    return '[ve středu v] LT';
	                case 4:
	                    return '[ve čtvrtek v] LT';
	                case 5:
	                    return '[v pátek v] LT';
	                case 6:
	                    return '[v sobotu v] LT';
	            }
	        },
	        lastDay: '[včera v] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[minulou neděli v] LT';
	                case 1:
	                case 2:
	                    return '[minulé] dddd [v] LT';
	                case 3:
	                    return '[minulou středu v] LT';
	                case 4:
	                case 5:
	                    return '[minulý] dddd [v] LT';
	                case 6:
	                    return '[minulou sobotu v] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : 'před %s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    ordinalParse : /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return cs;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chuvash [cv]
	//! author : Anatoly Mironov : https://github.com/mirontoli
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var cv = moment.defineLocale('cv', {
	    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),
	    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
	    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),
	    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
	    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
	        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
	        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
	    },
	    calendar : {
	        sameDay: '[Паян] LT [сехетре]',
	        nextDay: '[Ыран] LT [сехетре]',
	        lastDay: '[Ӗнер] LT [сехетре]',
	        nextWeek: '[Ҫитес] dddd LT [сехетре]',
	        lastWeek: '[Иртнӗ] dddd LT [сехетре]',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : function (output) {
	            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';
	            return output + affix;
	        },
	        past : '%s каялла',
	        s : 'пӗр-ик ҫеккунт',
	        m : 'пӗр минут',
	        mm : '%d минут',
	        h : 'пӗр сехет',
	        hh : '%d сехет',
	        d : 'пӗр кун',
	        dd : '%d кун',
	        M : 'пӗр уйӑх',
	        MM : '%d уйӑх',
	        y : 'пӗр ҫул',
	        yy : '%d ҫул'
	    },
	    ordinalParse: /\d{1,2}-мӗш/,
	    ordinal : '%d-мӗш',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return cv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Welsh [cy]
	//! author : Robert Allen : https://github.com/robgallen
	//! author : https://github.com/ryangreaves
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var cy = moment.defineLocale('cy', {
	    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),
	    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),
	    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),
	    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
	    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
	    weekdaysParseExact : true,
	    // time formats are the same as en-gb
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[Heddiw am] LT',
	        nextDay: '[Yfory am] LT',
	        nextWeek: 'dddd [am] LT',
	        lastDay: '[Ddoe am] LT',
	        lastWeek: 'dddd [diwethaf am] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'mewn %s',
	        past: '%s yn ôl',
	        s: 'ychydig eiliadau',
	        m: 'munud',
	        mm: '%d munud',
	        h: 'awr',
	        hh: '%d awr',
	        d: 'diwrnod',
	        dd: '%d diwrnod',
	        M: 'mis',
	        MM: '%d mis',
	        y: 'blwyddyn',
	        yy: '%d flynedd'
	    },
	    ordinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
	    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
	    ordinal: function (number) {
	        var b = number,
	            output = '',
	            lookup = [
	                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
	                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
	            ];
	        if (b > 20) {
	            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
	                output = 'fed'; // not 30ain, 70ain or 90ain
	            } else {
	                output = 'ain';
	            }
	        } else if (b > 0) {
	            output = lookup[b];
	        }
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return cy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Danish [da]
	//! author : Ulrik Nielsen : https://github.com/mrbase
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var da = moment.defineLocale('da', {
	    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
	    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),
	    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[I dag kl.] LT',
	        nextDay : '[I morgen kl.] LT',
	        nextWeek : 'dddd [kl.] LT',
	        lastDay : '[I går kl.] LT',
	        lastWeek : '[sidste] dddd [kl] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s siden',
	        s : 'få sekunder',
	        m : 'et minut',
	        mm : '%d minutter',
	        h : 'en time',
	        hh : '%d timer',
	        d : 'en dag',
	        dd : '%d dage',
	        M : 'en måned',
	        MM : '%d måneder',
	        y : 'et år',
	        yy : '%d år'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return da;
	
	})));


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

	//! moment.js locale configuration
	//! locale : German [de]
	//! author : lluchs : https://github.com/lluchs
	//! author: Menelion Elensúle: https://github.com/Oire
	//! author : Mikolaj Dadela : https://github.com/mik01aj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var de = moment.defineLocale('de', {
	    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd, D. MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return de;
	
	})));


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

	//! moment.js locale configuration
	//! locale : German (Austria) [de-at]
	//! author : lluchs : https://github.com/lluchs
	//! author: Menelion Elensúle: https://github.com/Oire
	//! author : Martin Groller : https://github.com/MadMG
	//! author : Mikolaj Dadela : https://github.com/mik01aj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var deAt = moment.defineLocale('de-at', {
	    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd, D. MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return deAt;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Maldivian [dv]
	//! author : Jawish Hameed : https://github.com/jawish
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'ޖެނުއަރީ',
	    'ފެބްރުއަރީ',
	    'މާރިޗު',
	    'އޭޕްރީލު',
	    'މޭ',
	    'ޖޫން',
	    'ޖުލައި',
	    'އޯގަސްޓު',
	    'ސެޕްޓެމްބަރު',
	    'އޮކްޓޯބަރު',
	    'ނޮވެމްބަރު',
	    'ޑިސެމްބަރު'
	];
	var weekdays = [
	    'އާދިއްތަ',
	    'ހޯމަ',
	    'އަންގާރަ',
	    'ބުދަ',
	    'ބުރާސްފަތި',
	    'ހުކުރު',
	    'ހޮނިހިރު'
	];
	
	var dv = moment.defineLocale('dv', {
	    months : months,
	    monthsShort : months,
	    weekdays : weekdays,
	    weekdaysShort : weekdays,
	    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),
	    longDateFormat : {
	
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/M/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /މކ|މފ/,
	    isPM : function (input) {
	        return 'މފ' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'މކ';
	        } else {
	            return 'މފ';
	        }
	    },
	    calendar : {
	        sameDay : '[މިއަދު] LT',
	        nextDay : '[މާދަމާ] LT',
	        nextWeek : 'dddd LT',
	        lastDay : '[އިއްޔެ] LT',
	        lastWeek : '[ފާއިތުވި] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ތެރޭގައި %s',
	        past : 'ކުރިން %s',
	        s : 'ސިކުންތުކޮޅެއް',
	        m : 'މިނިޓެއް',
	        mm : 'މިނިޓު %d',
	        h : 'ގަޑިއިރެއް',
	        hh : 'ގަޑިއިރު %d',
	        d : 'ދުވަހެއް',
	        dd : 'ދުވަސް %d',
	        M : 'މަހެއް',
	        MM : 'މަސް %d',
	        y : 'އަހަރެއް',
	        yy : 'އަހަރު %d'
	    },
	    preparse: function (string) {
	        return string.replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/,/g, '،');
	    },
	    week : {
	        dow : 7,  // Sunday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return dv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Greek [el]
	//! author : Aggelos Karalias : https://github.com/mehiel
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	function isFunction(input) {
	    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
	}
	
	
	var el = moment.defineLocale('el', {
	    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),
	    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),
	    months : function (momentToFormat, format) {
	        if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'
	            return this._monthsGenitiveEl[momentToFormat.month()];
	        } else {
	            return this._monthsNominativeEl[momentToFormat.month()];
	        }
	    },
	    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
	    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),
	    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),
	    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'μμ' : 'ΜΜ';
	        } else {
	            return isLower ? 'πμ' : 'ΠΜ';
	        }
	    },
	    isPM : function (input) {
	        return ((input + '').toLowerCase()[0] === 'μ');
	    },
	    meridiemParse : /[ΠΜ]\.?Μ?\.?/i,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendarEl : {
	        sameDay : '[Σήμερα {}] LT',
	        nextDay : '[Αύριο {}] LT',
	        nextWeek : 'dddd [{}] LT',
	        lastDay : '[Χθες {}] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 6:
	                    return '[το προηγούμενο] dddd [{}] LT';
	                default:
	                    return '[την προηγούμενη] dddd [{}] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    calendar : function (key, mom) {
	        var output = this._calendarEl[key],
	            hours = mom && mom.hours();
	        if (isFunction(output)) {
	            output = output.apply(mom);
	        }
	        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));
	    },
	    relativeTime : {
	        future : 'σε %s',
	        past : '%s πριν',
	        s : 'λίγα δευτερόλεπτα',
	        m : 'ένα λεπτό',
	        mm : '%d λεπτά',
	        h : 'μία ώρα',
	        hh : '%d ώρες',
	        d : 'μία μέρα',
	        dd : '%d μέρες',
	        M : 'ένας μήνας',
	        MM : '%d μήνες',
	        y : 'ένας χρόνος',
	        yy : '%d χρόνια'
	    },
	    ordinalParse: /\d{1,2}η/,
	    ordinal: '%dη',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4st is the first week of the year.
	    }
	});
	
	return el;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (Australia) [en-au]
	//! author : Jared Morse : https://github.com/jarcoal
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enAu = moment.defineLocale('en-au', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    ordinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enAu;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (Canada) [en-ca]
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enCa = moment.defineLocale('en-ca', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'YYYY-MM-DD',
	        LL : 'MMMM D, YYYY',
	        LLL : 'MMMM D, YYYY h:mm A',
	        LLLL : 'dddd, MMMM D, YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    ordinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    }
	});
	
	return enCa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (United Kingdom) [en-gb]
	//! author : Chris Gedrim : https://github.com/chrisgedrim
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enGb = moment.defineLocale('en-gb', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    ordinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enGb;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (Ireland) [en-ie]
	//! author : Chris Cartlidge : https://github.com/chriscartlidge
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enIe = moment.defineLocale('en-ie', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    ordinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enIe;
	
	})));


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

	//! moment.js locale configuration
	//! locale : English (New Zealand) [en-nz]
	//! author : Luke McGregor : https://github.com/lukemcgregor
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enNz = moment.defineLocale('en-nz', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few 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'
	    },
	    ordinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enNz;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Esperanto [eo]
	//! author : Colin Dean : https://github.com/colindean
	//! komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko.
	//!          Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var eo = moment.defineLocale('eo', {
	    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),
	    weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'),
	    weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D[-an de] MMMM, YYYY',
	        LLL : 'D[-an de] MMMM, YYYY HH:mm',
	        LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm'
	    },
	    meridiemParse: /[ap]\.t\.m/i,
	    isPM: function (input) {
	        return input.charAt(0).toLowerCase() === 'p';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'p.t.m.' : 'P.T.M.';
	        } else {
	            return isLower ? 'a.t.m.' : 'A.T.M.';
	        }
	    },
	    calendar : {
	        sameDay : '[Hodiaŭ je] LT',
	        nextDay : '[Morgaŭ je] LT',
	        nextWeek : 'dddd [je] LT',
	        lastDay : '[Hieraŭ je] LT',
	        lastWeek : '[pasinta] dddd [je] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'je %s',
	        past : 'antaŭ %s',
	        s : 'sekundoj',
	        m : 'minuto',
	        mm : '%d minutoj',
	        h : 'horo',
	        hh : '%d horoj',
	        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo
	        dd : '%d tagoj',
	        M : 'monato',
	        MM : '%d monatoj',
	        y : 'jaro',
	        yy : '%d jaroj'
	    },
	    ordinalParse: /\d{1,2}a/,
	    ordinal : '%da',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return eo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Spanish [es]
	//! author : Julio Napurí : https://github.com/julionc
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');
	var monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
	
	var es = moment.defineLocale('es', {
	    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),
	    monthsShort : function (m, format) {
	        if (/-MMM-/.test(format)) {
	            return monthsShort[m.month()];
	        } else {
	            return monthsShortDot[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY H:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastDay : function () {
	            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'en %s',
	        past : 'hace %s',
	        s : 'unos segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'una hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un año',
	        yy : '%d años'
	    },
	    ordinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return es;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Spanish (Dominican Republic) [es-do]
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');
	var monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
	
	var esDo = moment.defineLocale('es-do', {
	    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),
	    monthsShort : function (m, format) {
	        if (/-MMM-/.test(format)) {
	            return monthsShort[m.month()];
	        } else {
	            return monthsShortDot[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY h:mm A',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastDay : function () {
	            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'en %s',
	        past : 'hace %s',
	        s : 'unos segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'una hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un año',
	        yy : '%d años'
	    },
	    ordinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return esDo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Estonian [et]
	//! author : Henry Kehlmann : https://github.com/madhenry
	//! improvements : Illimar Tambek : https://github.com/ragulka
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
	        'm' : ['ühe minuti', 'üks minut'],
	        'mm': [number + ' minuti', number + ' minutit'],
	        'h' : ['ühe tunni', 'tund aega', 'üks tund'],
	        'hh': [number + ' tunni', number + ' tundi'],
	        'd' : ['ühe päeva', 'üks päev'],
	        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],
	        'MM': [number + ' kuu', number + ' kuud'],
	        'y' : ['ühe aasta', 'aasta', 'üks aasta'],
	        'yy': [number + ' aasta', number + ' aastat']
	    };
	    if (withoutSuffix) {
	        return format[key][2] ? format[key][2] : format[key][1];
	    }
	    return isFuture ? format[key][0] : format[key][1];
	}
	
	var et = moment.defineLocale('et', {
	    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),
	    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),
	    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),
	    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),
	    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),
	    longDateFormat : {
	        LT   : 'H:mm',
	        LTS : 'H:mm:ss',
	        L    : 'DD.MM.YYYY',
	        LL   : 'D. MMMM YYYY',
	        LLL  : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[Täna,] LT',
	        nextDay  : '[Homme,] LT',
	        nextWeek : '[Järgmine] dddd LT',
	        lastDay  : '[Eile,] LT',
	        lastWeek : '[Eelmine] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s pärast',
	        past   : '%s tagasi',
	        s      : processRelativeTime,
	        m      : processRelativeTime,
	        mm     : processRelativeTime,
	        h      : processRelativeTime,
	        hh     : processRelativeTime,
	        d      : processRelativeTime,
	        dd     : '%d päeva',
	        M      : processRelativeTime,
	        MM     : processRelativeTime,
	        y      : processRelativeTime,
	        yy     : processRelativeTime
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return et;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Basque [eu]
	//! author : Eneko Illarramendi : https://github.com/eillarra
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var eu = moment.defineLocale('eu', {
	    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),
	    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),
	    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),
	    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'YYYY[ko] MMMM[ren] D[a]',
	        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
	        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
	        l : 'YYYY-M-D',
	        ll : 'YYYY[ko] MMM D[a]',
	        lll : 'YYYY[ko] MMM D[a] HH:mm',
	        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
	    },
	    calendar : {
	        sameDay : '[gaur] LT[etan]',
	        nextDay : '[bihar] LT[etan]',
	        nextWeek : 'dddd LT[etan]',
	        lastDay : '[atzo] LT[etan]',
	        lastWeek : '[aurreko] dddd LT[etan]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s barru',
	        past : 'duela %s',
	        s : 'segundo batzuk',
	        m : 'minutu bat',
	        mm : '%d minutu',
	        h : 'ordu bat',
	        hh : '%d ordu',
	        d : 'egun bat',
	        dd : '%d egun',
	        M : 'hilabete bat',
	        MM : '%d hilabete',
	        y : 'urte bat',
	        yy : '%d urte'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return eu;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Persian [fa]
	//! author : Ebrahim Byagowi : https://github.com/ebraminio
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '۱',
	    '2': '۲',
	    '3': '۳',
	    '4': '۴',
	    '5': '۵',
	    '6': '۶',
	    '7': '۷',
	    '8': '۸',
	    '9': '۹',
	    '0': '۰'
	};
	var numberMap = {
	    '۱': '1',
	    '۲': '2',
	    '۳': '3',
	    '۴': '4',
	    '۵': '5',
	    '۶': '6',
	    '۷': '7',
	    '۸': '8',
	    '۹': '9',
	    '۰': '0'
	};
	
	var fa = moment.defineLocale('fa', {
	    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
	    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
	    weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
	    weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
	    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /قبل از ظهر|بعد از ظهر/,
	    isPM: function (input) {
	        return /بعد از ظهر/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'قبل از ظهر';
	        } else {
	            return 'بعد از ظهر';
	        }
	    },
	    calendar : {
	        sameDay : '[امروز ساعت] LT',
	        nextDay : '[فردا ساعت] LT',
	        nextWeek : 'dddd [ساعت] LT',
	        lastDay : '[دیروز ساعت] LT',
	        lastWeek : 'dddd [پیش] [ساعت] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'در %s',
	        past : '%s پیش',
	        s : 'چندین ثانیه',
	        m : 'یک دقیقه',
	        mm : '%d دقیقه',
	        h : 'یک ساعت',
	        hh : '%d ساعت',
	        d : 'یک روز',
	        dd : '%d روز',
	        M : 'یک ماه',
	        MM : '%d ماه',
	        y : 'یک سال',
	        yy : '%d سال'
	    },
	    preparse: function (string) {
	        return string.replace(/[۰-۹]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    ordinalParse: /\d{1,2}م/,
	    ordinal : '%dم',
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12 // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return fa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Finnish [fi]
	//! author : Tarmo Aidantausta : https://github.com/bleadof
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');
	var numbersFuture = [
	        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
	        numbersPast[7], numbersPast[8], numbersPast[9]
	    ];
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = '';
	    switch (key) {
	        case 's':
	            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
	        case 'm':
	            return isFuture ? 'minuutin' : 'minuutti';
	        case 'mm':
	            result = isFuture ? 'minuutin' : 'minuuttia';
	            break;
	        case 'h':
	            return isFuture ? 'tunnin' : 'tunti';
	        case 'hh':
	            result = isFuture ? 'tunnin' : 'tuntia';
	            break;
	        case 'd':
	            return isFuture ? 'päivän' : 'päivä';
	        case 'dd':
	            result = isFuture ? 'päivän' : 'päivää';
	            break;
	        case 'M':
	            return isFuture ? 'kuukauden' : 'kuukausi';
	        case 'MM':
	            result = isFuture ? 'kuukauden' : 'kuukautta';
	            break;
	        case 'y':
	            return isFuture ? 'vuoden' : 'vuosi';
	        case 'yy':
	            result = isFuture ? 'vuoden' : 'vuotta';
	            break;
	    }
	    result = verbalNumber(number, isFuture) + ' ' + result;
	    return result;
	}
	function verbalNumber(number, isFuture) {
	    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;
	}
	
	var fi = moment.defineLocale('fi', {
	    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),
	    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),
	    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),
	    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),
	    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'Do MMMM[ta] YYYY',
	        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
	        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
	        l : 'D.M.YYYY',
	        ll : 'Do MMM YYYY',
	        lll : 'Do MMM YYYY, [klo] HH.mm',
	        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
	    },
	    calendar : {
	        sameDay : '[tänään] [klo] LT',
	        nextDay : '[huomenna] [klo] LT',
	        nextWeek : 'dddd [klo] LT',
	        lastDay : '[eilen] [klo] LT',
	        lastWeek : '[viime] dddd[na] [klo] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s päästä',
	        past : '%s sitten',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Faroese [fo]
	//! author : Ragnar Johannesen : https://github.com/ragnar123
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var fo = moment.defineLocale('fo', {
	    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
	    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),
	    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),
	    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D. MMMM, YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Í dag kl.] LT',
	        nextDay : '[Í morgin kl.] LT',
	        nextWeek : 'dddd [kl.] LT',
	        lastDay : '[Í gjár kl.] LT',
	        lastWeek : '[síðstu] dddd [kl] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'um %s',
	        past : '%s síðani',
	        s : 'fá sekund',
	        m : 'ein minutt',
	        mm : '%d minuttir',
	        h : 'ein tími',
	        hh : '%d tímar',
	        d : 'ein dagur',
	        dd : '%d dagar',
	        M : 'ein mánaði',
	        MM : '%d mánaðir',
	        y : 'eitt ár',
	        yy : '%d ár'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : French [fr]
	//! author : John Fischer : https://github.com/jfroffice
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var fr = moment.defineLocale('fr', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Aujourd\'hui à] LT',
	        nextDay: '[Demain à] LT',
	        nextWeek: 'dddd [à] LT',
	        lastDay: '[Hier à] LT',
	        lastWeek: 'dddd [dernier à] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    ordinalParse: /\d{1,2}(er|)/,
	    ordinal : function (number) {
	        return number + (number === 1 ? 'er' : '');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : French (Canada) [fr-ca]
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var frCa = moment.defineLocale('fr-ca', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Aujourd\'hui à] LT',
	        nextDay: '[Demain à] LT',
	        nextWeek: 'dddd [à] LT',
	        lastDay: '[Hier à] LT',
	        lastWeek: 'dddd [dernier à] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    ordinalParse: /\d{1,2}(er|e)/,
	    ordinal : function (number) {
	        return number + (number === 1 ? 'er' : 'e');
	    }
	});
	
	return frCa;
	
	})));


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

	//! moment.js locale configuration
	//! locale : French (Switzerland) [fr-ch]
	//! author : Gaspard Bucher : https://github.com/gaspard
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var frCh = moment.defineLocale('fr-ch', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Aujourd\'hui à] LT',
	        nextDay: '[Demain à] LT',
	        nextWeek: 'dddd [à] LT',
	        lastDay: '[Hier à] LT',
	        lastWeek: 'dddd [dernier à] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    ordinalParse: /\d{1,2}(er|e)/,
	    ordinal : function (number) {
	        return number + (number === 1 ? 'er' : 'e');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return frCh;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Frisian [fy]
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');
	
	var fy = moment.defineLocale('fy', {
	    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),
	    monthsShort : function (m, format) {
	        if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),
	    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),
	    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[hjoed om] LT',
	        nextDay: '[moarn om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[juster om] LT',
	        lastWeek: '[ôfrûne] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'oer %s',
	        past : '%s lyn',
	        s : 'in pear sekonden',
	        m : 'ien minút',
	        mm : '%d minuten',
	        h : 'ien oere',
	        hh : '%d oeren',
	        d : 'ien dei',
	        dd : '%d dagen',
	        M : 'ien moanne',
	        MM : '%d moannen',
	        y : 'ien jier',
	        yy : '%d jierren'
	    },
	    ordinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Scottish Gaelic [gd]
	//! author : Jon Ashdown : https://github.com/jonashdown
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'
	];
	
	var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];
	
	var weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];
	
	var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];
	
	var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];
	
	var gd = moment.defineLocale('gd', {
	    months : months,
	    monthsShort : monthsShort,
	    monthsParseExact : true,
	    weekdays : weekdays,
	    weekdaysShort : weekdaysShort,
	    weekdaysMin : weekdaysMin,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[An-diugh aig] LT',
	        nextDay : '[A-màireach aig] LT',
	        nextWeek : 'dddd [aig] LT',
	        lastDay : '[An-dè aig] LT',
	        lastWeek : 'dddd [seo chaidh] [aig] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ann an %s',
	        past : 'bho chionn %s',
	        s : 'beagan diogan',
	        m : 'mionaid',
	        mm : '%d mionaidean',
	        h : 'uair',
	        hh : '%d uairean',
	        d : 'latha',
	        dd : '%d latha',
	        M : 'mìos',
	        MM : '%d mìosan',
	        y : 'bliadhna',
	        yy : '%d bliadhna'
	    },
	    ordinalParse : /\d{1,2}(d|na|mh)/,
	    ordinal : function (number) {
	        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return gd;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Galician [gl]
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var gl = moment.defineLocale('gl', {
	    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),
	    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY H:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
	        },
	        lastDay : function () {
	            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';
	        },
	        lastWeek : function () {
	            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : function (str) {
	            if (str.indexOf('un') === 0) {
	                return 'n' + str;
	            }
	            return 'en ' + str;
	        },
	        past : 'hai %s',
	        s : 'uns segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'unha hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un ano',
	        yy : '%d anos'
	    },
	    ordinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return gl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Hebrew [he]
	//! author : Tomer Cohen : https://github.com/tomer
	//! author : Moshe Simantov : https://github.com/DevelopmentIL
	//! author : Tal Ater : https://github.com/TalAter
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var he = moment.defineLocale('he', {
	    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),
	    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),
	    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),
	    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),
	    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [ב]MMMM YYYY',
	        LLL : 'D [ב]MMMM YYYY HH:mm',
	        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
	        l : 'D/M/YYYY',
	        ll : 'D MMM YYYY',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd, D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[היום ב־]LT',
	        nextDay : '[מחר ב־]LT',
	        nextWeek : 'dddd [בשעה] LT',
	        lastDay : '[אתמול ב־]LT',
	        lastWeek : '[ביום] dddd [האחרון בשעה] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'בעוד %s',
	        past : 'לפני %s',
	        s : 'מספר שניות',
	        m : 'דקה',
	        mm : '%d דקות',
	        h : 'שעה',
	        hh : function (number) {
	            if (number === 2) {
	                return 'שעתיים';
	            }
	            return number + ' שעות';
	        },
	        d : 'יום',
	        dd : function (number) {
	            if (number === 2) {
	                return 'יומיים';
	            }
	            return number + ' ימים';
	        },
	        M : 'חודש',
	        MM : function (number) {
	            if (number === 2) {
	                return 'חודשיים';
	            }
	            return number + ' חודשים';
	        },
	        y : 'שנה',
	        yy : function (number) {
	            if (number === 2) {
	                return 'שנתיים';
	            } else if (number % 10 === 0 && number !== 10) {
	                return number + ' שנה';
	            }
	            return number + ' שנים';
	        }
	    },
	    meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,
	    isPM : function (input) {
	        return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 5) {
	            return 'לפנות בוקר';
	        } else if (hour < 10) {
	            return 'בבוקר';
	        } else if (hour < 12) {
	            return isLower ? 'לפנה"צ' : 'לפני הצהריים';
	        } else if (hour < 18) {
	            return isLower ? 'אחה"צ' : 'אחרי הצהריים';
	        } else {
	            return 'בערב';
	        }
	    }
	});
	
	return he;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Hindi [hi]
	//! author : Mayank Singhal : https://github.com/mayanksinghal
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	var hi = moment.defineLocale('hi', {
	    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),
	    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
	    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),
	    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm बजे',
	        LTS : 'A h:mm:ss बजे',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm बजे',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[कल] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[कल] LT',
	        lastWeek : '[पिछले] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s में',
	        past : '%s पहले',
	        s : 'कुछ ही क्षण',
	        m : 'एक मिनट',
	        mm : '%d मिनट',
	        h : 'एक घंटा',
	        hh : '%d घंटे',
	        d : 'एक दिन',
	        dd : '%d दिन',
	        M : 'एक महीने',
	        MM : '%d महीने',
	        y : 'एक वर्ष',
	        yy : '%d वर्ष'
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // Hindi notation for meridiems are quite fuzzy in practice. While there exists
	    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
	    meridiemParse: /रात|सुबह|दोपहर|शाम/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'रात') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'सुबह') {
	            return hour;
	        } else if (meridiem === 'दोपहर') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'शाम') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'रात';
	        } else if (hour < 10) {
	            return 'सुबह';
	        } else if (hour < 17) {
	            return 'दोपहर';
	        } else if (hour < 20) {
	            return 'शाम';
	        } else {
	            return 'रात';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return hi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Croatian [hr]
	//! author : Bojan Marković : https://github.com/bmarkovic
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
	        case 'mm':
	            if (number === 1) {
	                result += 'minuta';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'minute';
	            } else {
	                result += 'minuta';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'jedan sat' : 'jednog sata';
	        case 'hh':
	            if (number === 1) {
	                result += 'sat';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'sata';
	            } else {
	                result += 'sati';
	            }
	            return result;
	        case 'dd':
	            if (number === 1) {
	                result += 'dan';
	            } else {
	                result += 'dana';
	            }
	            return result;
	        case 'MM':
	            if (number === 1) {
	                result += 'mjesec';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'mjeseca';
	            } else {
	                result += 'mjeseci';
	            }
	            return result;
	        case 'yy':
	            if (number === 1) {
	                result += 'godina';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'godine';
	            } else {
	                result += 'godina';
	            }
	            return result;
	    }
	}
	
	var hr = moment.defineLocale('hr', {
	    months : {
	        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),
	        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')
	    },
	    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danas u] LT',
	        nextDay  : '[sutra u] LT',
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[jučer u] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                    return '[prošlu] dddd [u] LT';
	                case 6:
	                    return '[prošle] [subote] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prošli] dddd [u] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'par sekundi',
	        m      : translate,
	        mm     : translate,
	        h      : translate,
	        hh     : translate,
	        d      : 'dan',
	        dd     : translate,
	        M      : 'mjesec',
	        MM     : translate,
	        y      : 'godinu',
	        yy     : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return hr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Hungarian [hu]
	//! author : Adam Brunner : https://github.com/adambrunner
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
	function translate(number, withoutSuffix, key, isFuture) {
	    var num = number,
	        suffix;
	    switch (key) {
	        case 's':
	            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
	        case 'm':
	            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
	        case 'mm':
	            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
	        case 'h':
	            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
	        case 'hh':
	            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
	        case 'd':
	            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
	        case 'dd':
	            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
	        case 'M':
	            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
	        case 'MM':
	            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
	        case 'y':
	            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
	        case 'yy':
	            return num + (isFuture || withoutSuffix ? ' év' : ' éve');
	    }
	    return '';
	}
	function week(isFuture) {
	    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
	}
	
	var hu = moment.defineLocale('hu', {
	    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),
	    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),
	    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),
	    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),
	    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'YYYY.MM.DD.',
	        LL : 'YYYY. MMMM D.',
	        LLL : 'YYYY. MMMM D. H:mm',
	        LLLL : 'YYYY. MMMM D., dddd H:mm'
	    },
	    meridiemParse: /de|du/i,
	    isPM: function (input) {
	        return input.charAt(1).toLowerCase() === 'u';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower === true ? 'de' : 'DE';
	        } else {
	            return isLower === true ? 'du' : 'DU';
	        }
	    },
	    calendar : {
	        sameDay : '[ma] LT[-kor]',
	        nextDay : '[holnap] LT[-kor]',
	        nextWeek : function () {
	            return week.call(this, true);
	        },
	        lastDay : '[tegnap] LT[-kor]',
	        lastWeek : function () {
	            return week.call(this, false);
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s múlva',
	        past : '%s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return hu;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Armenian [hy-am]
	//! author : Armendarabyan : https://github.com/armendarabyan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var hyAm = moment.defineLocale('hy-am', {
	    months : {
	        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),
	        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')
	    },
	    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),
	    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),
	    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
	    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY թ.',
	        LLL : 'D MMMM YYYY թ., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'
	    },
	    calendar : {
	        sameDay: '[այսօր] LT',
	        nextDay: '[վաղը] LT',
	        lastDay: '[երեկ] LT',
	        nextWeek: function () {
	            return 'dddd [օրը ժամը] LT';
	        },
	        lastWeek: function () {
	            return '[անցած] dddd [օրը ժամը] LT';
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s հետո',
	        past : '%s առաջ',
	        s : 'մի քանի վայրկյան',
	        m : 'րոպե',
	        mm : '%d րոպե',
	        h : 'ժամ',
	        hh : '%d ժամ',
	        d : 'օր',
	        dd : '%d օր',
	        M : 'ամիս',
	        MM : '%d ամիս',
	        y : 'տարի',
	        yy : '%d տարի'
	    },
	    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,
	    isPM: function (input) {
	        return /^(ցերեկվա|երեկոյան)$/.test(input);
	    },
	    meridiem : function (hour) {
	        if (hour < 4) {
	            return 'գիշերվա';
	        } else if (hour < 12) {
	            return 'առավոտվա';
	        } else if (hour < 17) {
	            return 'ցերեկվա';
	        } else {
	            return 'երեկոյան';
	        }
	    },
	    ordinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'DDD':
	            case 'w':
	            case 'W':
	            case 'DDDo':
	                if (number === 1) {
	                    return number + '-ին';
	                }
	                return number + '-րդ';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return hyAm;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Indonesian [id]
	//! author : Mohammad Satrio Utomo : https://github.com/tyok
	//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var id = moment.defineLocale('id', {
	    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),
	    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),
	    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|siang|sore|malam/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'siang') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'sore' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'siang';
	        } else if (hours < 19) {
	            return 'sore';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Besok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kemarin pukul] LT',
	        lastWeek : 'dddd [lalu pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lalu',
	        s : 'beberapa detik',
	        m : 'semenit',
	        mm : '%d menit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return id;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Icelandic [is]
	//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(n) {
	    if (n % 100 === 11) {
	        return true;
	    } else if (n % 10 === 1) {
	        return false;
	    }
	    return true;
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':
	            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';
	        case 'm':
	            return withoutSuffix ? 'mínúta' : 'mínútu';
	        case 'mm':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');
	            } else if (withoutSuffix) {
	                return result + 'mínúta';
	            }
	            return result + 'mínútu';
	        case 'hh':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');
	            }
	            return result + 'klukkustund';
	        case 'd':
	            if (withoutSuffix) {
	                return 'dagur';
	            }
	            return isFuture ? 'dag' : 'degi';
	        case 'dd':
	            if (plural(number)) {
	                if (withoutSuffix) {
	                    return result + 'dagar';
	                }
	                return result + (isFuture ? 'daga' : 'dögum');
	            } else if (withoutSuffix) {
	                return result + 'dagur';
	            }
	            return result + (isFuture ? 'dag' : 'degi');
	        case 'M':
	            if (withoutSuffix) {
	                return 'mánuður';
	            }
	            return isFuture ? 'mánuð' : 'mánuði';
	        case 'MM':
	            if (plural(number)) {
	                if (withoutSuffix) {
	                    return result + 'mánuðir';
	                }
	                return result + (isFuture ? 'mánuði' : 'mánuðum');
	            } else if (withoutSuffix) {
	                return result + 'mánuður';
	            }
	            return result + (isFuture ? 'mánuð' : 'mánuði');
	        case 'y':
	            return withoutSuffix || isFuture ? 'ár' : 'ári';
	        case 'yy':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
	            }
	            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
	    }
	}
	
	var is = moment.defineLocale('is', {
	    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),
	    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),
	    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),
	    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] H:mm',
	        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
	    },
	    calendar : {
	        sameDay : '[í dag kl.] LT',
	        nextDay : '[á morgun kl.] LT',
	        nextWeek : 'dddd [kl.] LT',
	        lastDay : '[í gær kl.] LT',
	        lastWeek : '[síðasta] dddd [kl.] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'eftir %s',
	        past : 'fyrir %s síðan',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : 'klukkustund',
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return is;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Italian [it]
	//! author : Lorenzo : https://github.com/aliem
	//! author: Mattia Larentis: https://github.com/nostalgiaz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var it = moment.defineLocale('it', {
	    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),
	    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
	    weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'),
	    weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'),
	    weekdaysMin : 'Do_Lu_Ma_Me_Gi_Ve_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Oggi alle] LT',
	        nextDay: '[Domani alle] LT',
	        nextWeek: 'dddd [alle] LT',
	        lastDay: '[Ieri alle] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[la scorsa] dddd [alle] LT';
	                default:
	                    return '[lo scorso] dddd [alle] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : function (s) {
	            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;
	        },
	        past : '%s fa',
	        s : 'alcuni secondi',
	        m : 'un minuto',
	        mm : '%d minuti',
	        h : 'un\'ora',
	        hh : '%d ore',
	        d : 'un giorno',
	        dd : '%d giorni',
	        M : 'un mese',
	        MM : '%d mesi',
	        y : 'un anno',
	        yy : '%d anni'
	    },
	    ordinalParse : /\d{1,2}º/,
	    ordinal: '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return it;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Japanese [ja]
	//! author : LI Long : https://github.com/baryon
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ja = moment.defineLocale('ja', {
	    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
	    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),
	    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
	    longDateFormat : {
	        LT : 'Ah時m分',
	        LTS : 'Ah時m分s秒',
	        L : 'YYYY/MM/DD',
	        LL : 'YYYY年M月D日',
	        LLL : 'YYYY年M月D日Ah時m分',
	        LLLL : 'YYYY年M月D日Ah時m分 dddd'
	    },
	    meridiemParse: /午前|午後/i,
	    isPM : function (input) {
	        return input === '午後';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return '午前';
	        } else {
	            return '午後';
	        }
	    },
	    calendar : {
	        sameDay : '[今日] LT',
	        nextDay : '[明日] LT',
	        nextWeek : '[来週]dddd LT',
	        lastDay : '[昨日] LT',
	        lastWeek : '[前週]dddd LT',
	        sameElse : 'L'
	    },
	    ordinalParse : /\d{1,2}日/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd':
	            case 'D':
	            case 'DDD':
	                return number + '日';
	            default:
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s後',
	        past : '%s前',
	        s : '数秒',
	        m : '1分',
	        mm : '%d分',
	        h : '1時間',
	        hh : '%d時間',
	        d : '1日',
	        dd : '%d日',
	        M : '1ヶ月',
	        MM : '%dヶ月',
	        y : '1年',
	        yy : '%d年'
	    }
	});
	
	return ja;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Javanese [jv]
	//! author : Rony Lantip : https://github.com/lantip
	//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var jv = moment.defineLocale('jv', {
	    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),
	    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),
	    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),
	    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /enjing|siyang|sonten|ndalu/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'enjing') {
	            return hour;
	        } else if (meridiem === 'siyang') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'enjing';
	        } else if (hours < 15) {
	            return 'siyang';
	        } else if (hours < 19) {
	            return 'sonten';
	        } else {
	            return 'ndalu';
	        }
	    },
	    calendar : {
	        sameDay : '[Dinten puniko pukul] LT',
	        nextDay : '[Mbenjang pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kala wingi pukul] LT',
	        lastWeek : 'dddd [kepengker pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'wonten ing %s',
	        past : '%s ingkang kepengker',
	        s : 'sawetawis detik',
	        m : 'setunggal menit',
	        mm : '%d menit',
	        h : 'setunggal jam',
	        hh : '%d jam',
	        d : 'sedinten',
	        dd : '%d dinten',
	        M : 'sewulan',
	        MM : '%d wulan',
	        y : 'setaun',
	        yy : '%d taun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return jv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Georgian [ka]
	//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ka = moment.defineLocale('ka', {
	    months : {
	        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
	        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')
	    },
	    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),
	    weekdays : {
	        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),
	        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),
	        isFormat: /(წინა|შემდეგ)/
	    },
	    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),
	    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[დღეს] LT[-ზე]',
	        nextDay : '[ხვალ] LT[-ზე]',
	        lastDay : '[გუშინ] LT[-ზე]',
	        nextWeek : '[შემდეგ] dddd LT[-ზე]',
	        lastWeek : '[წინა] dddd LT-ზე',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : function (s) {
	            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?
	                s.replace(/ი$/, 'ში') :
	                s + 'ში';
	        },
	        past : function (s) {
	            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {
	                return s.replace(/(ი|ე)$/, 'ის წინ');
	            }
	            if ((/წელი/).test(s)) {
	                return s.replace(/წელი$/, 'წლის წინ');
	            }
	        },
	        s : 'რამდენიმე წამი',
	        m : 'წუთი',
	        mm : '%d წუთი',
	        h : 'საათი',
	        hh : '%d საათი',
	        d : 'დღე',
	        dd : '%d დღე',
	        M : 'თვე',
	        MM : '%d თვე',
	        y : 'წელი',
	        yy : '%d წელი'
	    },
	    ordinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,
	    ordinal : function (number) {
	        if (number === 0) {
	            return number;
	        }
	        if (number === 1) {
	            return number + '-ლი';
	        }
	        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {
	            return 'მე-' + number;
	        }
	        return number + '-ე';
	    },
	    week : {
	        dow : 1,
	        doy : 7
	    }
	});
	
	return ka;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Kazakh [kk]
	//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    0: '-ші',
	    1: '-ші',
	    2: '-ші',
	    3: '-ші',
	    4: '-ші',
	    5: '-ші',
	    6: '-шы',
	    7: '-ші',
	    8: '-ші',
	    9: '-шы',
	    10: '-шы',
	    20: '-шы',
	    30: '-шы',
	    40: '-шы',
	    50: '-ші',
	    60: '-шы',
	    70: '-ші',
	    80: '-ші',
	    90: '-шы',
	    100: '-ші'
	};
	
	var kk = moment.defineLocale('kk', {
	    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),
	    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),
	    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),
	    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),
	    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бүгін сағат] LT',
	        nextDay : '[Ертең сағат] LT',
	        nextWeek : 'dddd [сағат] LT',
	        lastDay : '[Кеше сағат] LT',
	        lastWeek : '[Өткен аптаның] dddd [сағат] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ішінде',
	        past : '%s бұрын',
	        s : 'бірнеше секунд',
	        m : 'бір минут',
	        mm : '%d минут',
	        h : 'бір сағат',
	        hh : '%d сағат',
	        d : 'бір күн',
	        dd : '%d күн',
	        M : 'бір ай',
	        MM : '%d ай',
	        y : 'бір жыл',
	        yy : '%d жыл'
	    },
	    ordinalParse: /\d{1,2}-(ші|шы)/,
	    ordinal : function (number) {
	        var a = number % 10,
	            b = number >= 100 ? 100 : null;
	        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return kk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Cambodian [km]
	//! author : Kruy Vanna : https://github.com/kruyvanna
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var km = moment.defineLocale('km', {
	    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
	    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
	    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',
	        nextDay: '[ស្អែក ម៉ោង] LT',
	        nextWeek: 'dddd [ម៉ោង] LT',
	        lastDay: '[ម្សិលមិញ ម៉ោង] LT',
	        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: '%sទៀត',
	        past: '%sមុន',
	        s: 'ប៉ុន្មានវិនាទី',
	        m: 'មួយនាទី',
	        mm: '%d នាទី',
	        h: 'មួយម៉ោង',
	        hh: '%d ម៉ោង',
	        d: 'មួយថ្ងៃ',
	        dd: '%d ថ្ងៃ',
	        M: 'មួយខែ',
	        MM: '%d ខែ',
	        y: 'មួយឆ្នាំ',
	        yy: '%d ឆ្នាំ'
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return km;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Korean [ko]
	//! author : Kyungwook, Park : https://github.com/kyungw00k
	//! author : Jeeeyul Lee <jeeeyul@gmail.com>
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ko = moment.defineLocale('ko', {
	    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
	    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
	    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),
	    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),
	    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),
	    longDateFormat : {
	        LT : 'A h시 m분',
	        LTS : 'A h시 m분 s초',
	        L : 'YYYY.MM.DD',
	        LL : 'YYYY년 MMMM D일',
	        LLL : 'YYYY년 MMMM D일 A h시 m분',
	        LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'
	    },
	    calendar : {
	        sameDay : '오늘 LT',
	        nextDay : '내일 LT',
	        nextWeek : 'dddd LT',
	        lastDay : '어제 LT',
	        lastWeek : '지난주 dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s 후',
	        past : '%s 전',
	        s : '몇 초',
	        ss : '%d초',
	        m : '일분',
	        mm : '%d분',
	        h : '한 시간',
	        hh : '%d시간',
	        d : '하루',
	        dd : '%d일',
	        M : '한 달',
	        MM : '%d달',
	        y : '일 년',
	        yy : '%d년'
	    },
	    ordinalParse : /\d{1,2}일/,
	    ordinal : '%d일',
	    meridiemParse : /오전|오후/,
	    isPM : function (token) {
	        return token === '오후';
	    },
	    meridiem : function (hour, minute, isUpper) {
	        return hour < 12 ? '오전' : '오후';
	    }
	});
	
	return ko;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Kyrgyz [ky]
	//! author : Chyngyz Arystan uulu : https://github.com/chyngyz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var suffixes = {
	    0: '-чү',
	    1: '-чи',
	    2: '-чи',
	    3: '-чү',
	    4: '-чү',
	    5: '-чи',
	    6: '-чы',
	    7: '-чи',
	    8: '-чи',
	    9: '-чу',
	    10: '-чу',
	    20: '-чы',
	    30: '-чу',
	    40: '-чы',
	    50: '-чү',
	    60: '-чы',
	    70: '-чи',
	    80: '-чи',
	    90: '-чу',
	    100: '-чү'
	};
	
	var ky = moment.defineLocale('ky', {
	    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
	    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),
	    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),
	    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),
	    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бүгүн саат] LT',
	        nextDay : '[Эртең саат] LT',
	        nextWeek : 'dddd [саат] LT',
	        lastDay : '[Кече саат] LT',
	        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ичинде',
	        past : '%s мурун',
	        s : 'бирнече секунд',
	        m : 'бир мүнөт',
	        mm : '%d мүнөт',
	        h : 'бир саат',
	        hh : '%d саат',
	        d : 'бир күн',
	        dd : '%d күн',
	        M : 'бир ай',
	        MM : '%d ай',
	        y : 'бир жыл',
	        yy : '%d жыл'
	    },
	    ordinalParse: /\d{1,2}-(чи|чы|чү|чу)/,
	    ordinal : function (number) {
	        var a = number % 10,
	            b = number >= 100 ? 100 : null;
	        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ky;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Luxembourgish [lb]
	//! author : mweimerskirch : https://github.com/mweimerskirch
	//! author : David Raison : https://github.com/kwisatz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eng Minutt', 'enger Minutt'],
	        'h': ['eng Stonn', 'enger Stonn'],
	        'd': ['een Dag', 'engem Dag'],
	        'M': ['ee Mount', 'engem Mount'],
	        'y': ['ee Joer', 'engem Joer']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	function processFutureTime(string) {
	    var number = string.substr(0, string.indexOf(' '));
	    if (eifelerRegelAppliesToNumber(number)) {
	        return 'a ' + string;
	    }
	    return 'an ' + string;
	}
	function processPastTime(string) {
	    var number = string.substr(0, string.indexOf(' '));
	    if (eifelerRegelAppliesToNumber(number)) {
	        return 'viru ' + string;
	    }
	    return 'virun ' + string;
	}
	/**
	 * Returns true if the word before the given number loses the '-n' ending.
	 * e.g. 'an 10 Deeg' but 'a 5 Deeg'
	 *
	 * @param number {integer}
	 * @returns {boolean}
	 */
	function eifelerRegelAppliesToNumber(number) {
	    number = parseInt(number, 10);
	    if (isNaN(number)) {
	        return false;
	    }
	    if (number < 0) {
	        // Negative Number --> always true
	        return true;
	    } else if (number < 10) {
	        // Only 1 digit
	        if (4 <= number && number <= 7) {
	            return true;
	        }
	        return false;
	    } else if (number < 100) {
	        // 2 digits
	        var lastDigit = number % 10, firstDigit = number / 10;
	        if (lastDigit === 0) {
	            return eifelerRegelAppliesToNumber(firstDigit);
	        }
	        return eifelerRegelAppliesToNumber(lastDigit);
	    } else if (number < 10000) {
	        // 3 or 4 digits --> recursively check first digit
	        while (number >= 10) {
	            number = number / 10;
	        }
	        return eifelerRegelAppliesToNumber(number);
	    } else {
	        // Anything larger than 4 digits: recursively check first n-3 digits
	        number = number / 1000;
	        return eifelerRegelAppliesToNumber(number);
	    }
	}
	
	var lb = moment.defineLocale('lb', {
	    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),
	    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),
	    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm [Auer]',
	        LTS: 'H:mm:ss [Auer]',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm [Auer]',
	        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
	    },
	    calendar: {
	        sameDay: '[Haut um] LT',
	        sameElse: 'L',
	        nextDay: '[Muer um] LT',
	        nextWeek: 'dddd [um] LT',
	        lastDay: '[Gëschter um] LT',
	        lastWeek: function () {
	            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule
	            switch (this.day()) {
	                case 2:
	                case 4:
	                    return '[Leschten] dddd [um] LT';
	                default:
	                    return '[Leschte] dddd [um] LT';
	            }
	        }
	    },
	    relativeTime : {
	        future : processFutureTime,
	        past : processPastTime,
	        s : 'e puer Sekonnen',
	        m : processRelativeTime,
	        mm : '%d Minutten',
	        h : processRelativeTime,
	        hh : '%d Stonnen',
	        d : processRelativeTime,
	        dd : '%d Deeg',
	        M : processRelativeTime,
	        MM : '%d Méint',
	        y : processRelativeTime,
	        yy : '%d Joer'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal: '%d.',
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lb;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Lao [lo]
	//! author : Ryan Hart : https://github.com/ryanhart2
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var lo = moment.defineLocale('lo', {
	    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),
	    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),
	    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
	    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
	    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,
	    isPM: function (input) {
	        return input === 'ຕອນແລງ';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ຕອນເຊົ້າ';
	        } else {
	            return 'ຕອນແລງ';
	        }
	    },
	    calendar : {
	        sameDay : '[ມື້ນີ້ເວລາ] LT',
	        nextDay : '[ມື້ອື່ນເວລາ] LT',
	        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',
	        lastDay : '[ມື້ວານນີ້ເວລາ] LT',
	        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ອີກ %s',
	        past : '%sຜ່ານມາ',
	        s : 'ບໍ່ເທົ່າໃດວິນາທີ',
	        m : '1 ນາທີ',
	        mm : '%d ນາທີ',
	        h : '1 ຊົ່ວໂມງ',
	        hh : '%d ຊົ່ວໂມງ',
	        d : '1 ມື້',
	        dd : '%d ມື້',
	        M : '1 ເດືອນ',
	        MM : '%d ເດືອນ',
	        y : '1 ປີ',
	        yy : '%d ປີ'
	    },
	    ordinalParse: /(ທີ່)\d{1,2}/,
	    ordinal : function (number) {
	        return 'ທີ່' + number;
	    }
	});
	
	return lo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Lithuanian [lt]
	//! author : Mindaugas Mozūras : https://github.com/mmozuras
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var units = {
	    'm' : 'minutė_minutės_minutę',
	    'mm': 'minutės_minučių_minutes',
	    'h' : 'valanda_valandos_valandą',
	    'hh': 'valandos_valandų_valandas',
	    'd' : 'diena_dienos_dieną',
	    'dd': 'dienos_dienų_dienas',
	    'M' : 'mėnuo_mėnesio_mėnesį',
	    'MM': 'mėnesiai_mėnesių_mėnesius',
	    'y' : 'metai_metų_metus',
	    'yy': 'metai_metų_metus'
	};
	function translateSeconds(number, withoutSuffix, key, isFuture) {
	    if (withoutSuffix) {
	        return 'kelios sekundės';
	    } else {
	        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
	    }
	}
	function translateSingular(number, withoutSuffix, key, isFuture) {
	    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
	}
	function special(number) {
	    return number % 10 === 0 || (number > 10 && number < 20);
	}
	function forms(key) {
	    return units[key].split('_');
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    if (number === 1) {
	        return result + translateSingular(number, withoutSuffix, key[0], isFuture);
	    } else if (withoutSuffix) {
	        return result + (special(number) ? forms(key)[1] : forms(key)[0]);
	    } else {
	        if (isFuture) {
	            return result + forms(key)[1];
	        } else {
	            return result + (special(number) ? forms(key)[1] : forms(key)[2]);
	        }
	    }
	}
	var lt = moment.defineLocale('lt', {
	    months : {
	        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
	        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
	        isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/
	    },
	    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
	    weekdays : {
	        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),
	        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),
	        isFormat: /dddd HH:mm/
	    },
	    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
	    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'YYYY [m.] MMMM D [d.]',
	        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
	        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
	        l : 'YYYY-MM-DD',
	        ll : 'YYYY [m.] MMMM D [d.]',
	        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
	        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
	    },
	    calendar : {
	        sameDay : '[Šiandien] LT',
	        nextDay : '[Rytoj] LT',
	        nextWeek : 'dddd LT',
	        lastDay : '[Vakar] LT',
	        lastWeek : '[Praėjusį] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'po %s',
	        past : 'prieš %s',
	        s : translateSeconds,
	        m : translateSingular,
	        mm : translate,
	        h : translateSingular,
	        hh : translate,
	        d : translateSingular,
	        dd : translate,
	        M : translateSingular,
	        MM : translate,
	        y : translateSingular,
	        yy : translate
	    },
	    ordinalParse: /\d{1,2}-oji/,
	    ordinal : function (number) {
	        return number + '-oji';
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lt;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Latvian [lv]
	//! author : Kristaps Karlsons : https://github.com/skakri
	//! author : Jānis Elmeris : https://github.com/JanisE
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var units = {
	    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
	    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
	    'h': 'stundas_stundām_stunda_stundas'.split('_'),
	    'hh': 'stundas_stundām_stunda_stundas'.split('_'),
	    'd': 'dienas_dienām_diena_dienas'.split('_'),
	    'dd': 'dienas_dienām_diena_dienas'.split('_'),
	    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
	    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
	    'y': 'gada_gadiem_gads_gadi'.split('_'),
	    'yy': 'gada_gadiem_gads_gadi'.split('_')
	};
	/**
	 * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.
	 */
	function format(forms, number, withoutSuffix) {
	    if (withoutSuffix) {
	        // E.g. "21 minūte", "3 minūtes".
	        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];
	    } else {
	        // E.g. "21 minūtes" as in "pēc 21 minūtes".
	        // E.g. "3 minūtēm" as in "pēc 3 minūtēm".
	        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];
	    }
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    return number + ' ' + format(units[key], number, withoutSuffix);
	}
	function relativeTimeWithSingular(number, withoutSuffix, key) {
	    return format(units[key], number, withoutSuffix);
	}
	function relativeSeconds(number, withoutSuffix) {
	    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';
	}
	
	var lv = moment.defineLocale('lv', {
	    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),
	    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),
	    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY.',
	        LL : 'YYYY. [gada] D. MMMM',
	        LLL : 'YYYY. [gada] D. MMMM, HH:mm',
	        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
	    },
	    calendar : {
	        sameDay : '[Šodien pulksten] LT',
	        nextDay : '[Rīt pulksten] LT',
	        nextWeek : 'dddd [pulksten] LT',
	        lastDay : '[Vakar pulksten] LT',
	        lastWeek : '[Pagājušā] dddd [pulksten] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'pēc %s',
	        past : 'pirms %s',
	        s : relativeSeconds,
	        m : relativeTimeWithSingular,
	        mm : relativeTimeWithPlural,
	        h : relativeTimeWithSingular,
	        hh : relativeTimeWithPlural,
	        d : relativeTimeWithSingular,
	        dd : relativeTimeWithPlural,
	        M : relativeTimeWithSingular,
	        MM : relativeTimeWithPlural,
	        y : relativeTimeWithSingular,
	        yy : relativeTimeWithPlural
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Montenegrin [me]
	//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['jedan minut', 'jednog minuta'],
	        mm: ['minut', 'minuta', 'minuta'],
	        h: ['jedan sat', 'jednog sata'],
	        hh: ['sat', 'sata', 'sati'],
	        dd: ['dan', 'dana', 'dana'],
	        MM: ['mjesec', 'mjeseca', 'mjeseci'],
	        yy: ['godina', 'godine', 'godina']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var me = moment.defineLocale('me', {
	    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact : true,
	    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[danas u] LT',
	        nextDay: '[sjutra u] LT',
	
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[juče u] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[prošle] [nedjelje] [u] LT',
	                '[prošlog] [ponedjeljka] [u] LT',
	                '[prošlog] [utorka] [u] LT',
	                '[prošle] [srijede] [u] LT',
	                '[prošlog] [četvrtka] [u] LT',
	                '[prošlog] [petka] [u] LT',
	                '[prošle] [subote] [u] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'nekoliko sekundi',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'dan',
	        dd     : translator.translate,
	        M      : 'mjesec',
	        MM     : translator.translate,
	        y      : 'godinu',
	        yy     : translator.translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return me;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Maori [mi]
	//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var mi = moment.defineLocale('mi', {
	    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),
	    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),
	    monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,
	    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),
	    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
	    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY [i] HH:mm',
	        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'
	    },
	    calendar: {
	        sameDay: '[i teie mahana, i] LT',
	        nextDay: '[apopo i] LT',
	        nextWeek: 'dddd [i] LT',
	        lastDay: '[inanahi i] LT',
	        lastWeek: 'dddd [whakamutunga i] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'i roto i %s',
	        past: '%s i mua',
	        s: 'te hēkona ruarua',
	        m: 'he meneti',
	        mm: '%d meneti',
	        h: 'te haora',
	        hh: '%d haora',
	        d: 'he ra',
	        dd: '%d ra',
	        M: 'he marama',
	        MM: '%d marama',
	        y: 'he tau',
	        yy: '%d tau'
	    },
	    ordinalParse: /\d{1,2}º/,
	    ordinal: '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return mi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Macedonian [mk]
	//! author : Borislav Mickov : https://github.com/B0k0
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var mk = moment.defineLocale('mk', {
	    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),
	    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),
	    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),
	    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),
	    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'D.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay : '[Денес во] LT',
	        nextDay : '[Утре во] LT',
	        nextWeek : '[Во] dddd [во] LT',
	        lastDay : '[Вчера во] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 6:
	                    return '[Изминатата] dddd [во] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[Изминатиот] dddd [во] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'после %s',
	        past : 'пред %s',
	        s : 'неколку секунди',
	        m : 'минута',
	        mm : '%d минути',
	        h : 'час',
	        hh : '%d часа',
	        d : 'ден',
	        dd : '%d дена',
	        M : 'месец',
	        MM : '%d месеци',
	        y : 'година',
	        yy : '%d години'
	    },
	    ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
	    ordinal : function (number) {
	        var lastDigit = number % 10,
	            last2Digits = number % 100;
	        if (number === 0) {
	            return number + '-ев';
	        } else if (last2Digits === 0) {
	            return number + '-ен';
	        } else if (last2Digits > 10 && last2Digits < 20) {
	            return number + '-ти';
	        } else if (lastDigit === 1) {
	            return number + '-ви';
	        } else if (lastDigit === 2) {
	            return number + '-ри';
	        } else if (lastDigit === 7 || lastDigit === 8) {
	            return number + '-ми';
	        } else {
	            return number + '-ти';
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return mk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Malayalam [ml]
	//! author : Floyd Pink : https://github.com/floydpink
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ml = moment.defineLocale('ml', {
	    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),
	    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),
	    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),
	    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm -നു',
	        LTS : 'A h:mm:ss -നു',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm -നു',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
	    },
	    calendar : {
	        sameDay : '[ഇന്ന്] LT',
	        nextDay : '[നാളെ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ഇന്നലെ] LT',
	        lastWeek : '[കഴിഞ്ഞ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s കഴിഞ്ഞ്',
	        past : '%s മുൻപ്',
	        s : 'അൽപ നിമിഷങ്ങൾ',
	        m : 'ഒരു മിനിറ്റ്',
	        mm : '%d മിനിറ്റ്',
	        h : 'ഒരു മണിക്കൂർ',
	        hh : '%d മണിക്കൂർ',
	        d : 'ഒരു ദിവസം',
	        dd : '%d ദിവസം',
	        M : 'ഒരു മാസം',
	        MM : '%d മാസം',
	        y : 'ഒരു വർഷം',
	        yy : '%d വർഷം'
	    },
	    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'രാത്രി' && hour >= 4) ||
	                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||
	                meridiem === 'വൈകുന്നേരം') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'രാത്രി';
	        } else if (hour < 12) {
	            return 'രാവിലെ';
	        } else if (hour < 17) {
	            return 'ഉച്ച കഴിഞ്ഞ്';
	        } else if (hour < 20) {
	            return 'വൈകുന്നേരം';
	        } else {
	            return 'രാത്രി';
	        }
	    }
	});
	
	return ml;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Marathi [mr]
	//! author : Harshad Kale : https://github.com/kalehv
	//! author : Vivek Athalye : https://github.com/vnathalye
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	function relativeTimeMr(number, withoutSuffix, string, isFuture)
	{
	    var output = '';
	    if (withoutSuffix) {
	        switch (string) {
	            case 's': output = 'काही सेकंद'; break;
	            case 'm': output = 'एक मिनिट'; break;
	            case 'mm': output = '%d मिनिटे'; break;
	            case 'h': output = 'एक तास'; break;
	            case 'hh': output = '%d तास'; break;
	            case 'd': output = 'एक दिवस'; break;
	            case 'dd': output = '%d दिवस'; break;
	            case 'M': output = 'एक महिना'; break;
	            case 'MM': output = '%d महिने'; break;
	            case 'y': output = 'एक वर्ष'; break;
	            case 'yy': output = '%d वर्षे'; break;
	        }
	    }
	    else {
	        switch (string) {
	            case 's': output = 'काही सेकंदां'; break;
	            case 'm': output = 'एका मिनिटा'; break;
	            case 'mm': output = '%d मिनिटां'; break;
	            case 'h': output = 'एका तासा'; break;
	            case 'hh': output = '%d तासां'; break;
	            case 'd': output = 'एका दिवसा'; break;
	            case 'dd': output = '%d दिवसां'; break;
	            case 'M': output = 'एका महिन्या'; break;
	            case 'MM': output = '%d महिन्यां'; break;
	            case 'y': output = 'एका वर्षा'; break;
	            case 'yy': output = '%d वर्षां'; break;
	        }
	    }
	    return output.replace(/%d/i, number);
	}
	
	var mr = moment.defineLocale('mr', {
	    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),
	    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
	    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),
	    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm वाजता',
	        LTS : 'A h:mm:ss वाजता',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm वाजता',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[उद्या] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[काल] LT',
	        lastWeek: '[मागील] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future: '%sमध्ये',
	        past: '%sपूर्वी',
	        s: relativeTimeMr,
	        m: relativeTimeMr,
	        mm: relativeTimeMr,
	        h: relativeTimeMr,
	        hh: relativeTimeMr,
	        d: relativeTimeMr,
	        dd: relativeTimeMr,
	        M: relativeTimeMr,
	        MM: relativeTimeMr,
	        y: relativeTimeMr,
	        yy: relativeTimeMr
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'रात्री') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'सकाळी') {
	            return hour;
	        } else if (meridiem === 'दुपारी') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'सायंकाळी') {
	            return hour + 12;
	        }
	    },
	    meridiem: function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'रात्री';
	        } else if (hour < 10) {
	            return 'सकाळी';
	        } else if (hour < 17) {
	            return 'दुपारी';
	        } else if (hour < 20) {
	            return 'सायंकाळी';
	        } else {
	            return 'रात्री';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return mr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Malay [ms]
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ms = moment.defineLocale('ms', {
	    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
	    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
	    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
	    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|tengahari|petang|malam/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'tengahari') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'petang' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'tengahari';
	        } else if (hours < 19) {
	            return 'petang';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Esok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kelmarin pukul] LT',
	        lastWeek : 'dddd [lepas pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lepas',
	        s : 'beberapa saat',
	        m : 'seminit',
	        mm : '%d minit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ms;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Malay [ms-my]
	//! note : DEPRECATED, the correct one is [ms]
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var msMy = moment.defineLocale('ms-my', {
	    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
	    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
	    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
	    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|tengahari|petang|malam/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'tengahari') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'petang' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'tengahari';
	        } else if (hours < 19) {
	            return 'petang';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Esok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kelmarin pukul] LT',
	        lastWeek : 'dddd [lepas pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lepas',
	        s : 'beberapa saat',
	        m : 'seminit',
	        mm : '%d minit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return msMy;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Burmese [my]
	//! author : Squar team, mysquar.com
	//! author : David Rossellat : https://github.com/gholadr
	//! author : Tin Aung Lin : https://github.com/thanyawzinmin
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '၁',
	    '2': '၂',
	    '3': '၃',
	    '4': '၄',
	    '5': '၅',
	    '6': '၆',
	    '7': '၇',
	    '8': '၈',
	    '9': '၉',
	    '0': '၀'
	};
	var numberMap = {
	    '၁': '1',
	    '၂': '2',
	    '၃': '3',
	    '၄': '4',
	    '၅': '5',
	    '၆': '6',
	    '၇': '7',
	    '၈': '8',
	    '၉': '9',
	    '၀': '0'
	};
	
	var my = moment.defineLocale('my', {
	    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),
	    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),
	    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),
	    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
	    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
	
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[ယနေ.] LT [မှာ]',
	        nextDay: '[မနက်ဖြန်] LT [မှာ]',
	        nextWeek: 'dddd LT [မှာ]',
	        lastDay: '[မနေ.က] LT [မှာ]',
	        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'လာမည့် %s မှာ',
	        past: 'လွန်ခဲ့သော %s က',
	        s: 'စက္ကန်.အနည်းငယ်',
	        m: 'တစ်မိနစ်',
	        mm: '%d မိနစ်',
	        h: 'တစ်နာရီ',
	        hh: '%d နာရီ',
	        d: 'တစ်ရက်',
	        dd: '%d ရက်',
	        M: 'တစ်လ',
	        MM: '%d လ',
	        y: 'တစ်နှစ်',
	        yy: '%d နှစ်'
	    },
	    preparse: function (string) {
	        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return my;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Norwegian Bokmål [nb]
	//! authors : Espen Hovlandsdal : https://github.com/rexxars
	//!           Sigurd Gartmann : https://github.com/sigurdga
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var nb = moment.defineLocale('nb', {
	    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
	    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),
	    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] HH:mm',
	        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[i dag kl.] LT',
	        nextDay: '[i morgen kl.] LT',
	        nextWeek: 'dddd [kl.] LT',
	        lastDay: '[i går kl.] LT',
	        lastWeek: '[forrige] dddd [kl.] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s siden',
	        s : 'noen sekunder',
	        m : 'ett minutt',
	        mm : '%d minutter',
	        h : 'en time',
	        hh : '%d timer',
	        d : 'en dag',
	        dd : '%d dager',
	        M : 'en måned',
	        MM : '%d måneder',
	        y : 'ett år',
	        yy : '%d år'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nb;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Nepalese [ne]
	//! author : suvash : https://github.com/suvash
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	var ne = moment.defineLocale('ne', {
	    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),
	    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),
	    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),
	    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'Aको h:mm बजे',
	        LTS : 'Aको h:mm:ss बजे',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, Aको h:mm बजे',
	        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'राति') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'बिहान') {
	            return hour;
	        } else if (meridiem === 'दिउँसो') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'साँझ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 3) {
	            return 'राति';
	        } else if (hour < 12) {
	            return 'बिहान';
	        } else if (hour < 16) {
	            return 'दिउँसो';
	        } else if (hour < 20) {
	            return 'साँझ';
	        } else {
	            return 'राति';
	        }
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[भोलि] LT',
	        nextWeek : '[आउँदो] dddd[,] LT',
	        lastDay : '[हिजो] LT',
	        lastWeek : '[गएको] dddd[,] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%sमा',
	        past : '%s अगाडि',
	        s : 'केही क्षण',
	        m : 'एक मिनेट',
	        mm : '%d मिनेट',
	        h : 'एक घण्टा',
	        hh : '%d घण्टा',
	        d : 'एक दिन',
	        dd : '%d दिन',
	        M : 'एक महिना',
	        MM : '%d महिना',
	        y : 'एक बर्ष',
	        yy : '%d बर्ष'
	    },
	    week : {
	        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.
	    }
	});
	
	return ne;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Dutch [nl]
	//! author : Joris Röling : https://github.com/jorisroling
	//! author : Jacob Middag : https://github.com/middagj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
	
	var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];
	var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
	
	var nl = moment.defineLocale('nl', {
	    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
	    monthsShort : function (m, format) {
	        if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	
	    monthsRegex: monthsRegex,
	    monthsShortRegex: monthsRegex,
	    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,
	    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
	
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
	    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
	    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[vandaag om] LT',
	        nextDay: '[morgen om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[gisteren om] LT',
	        lastWeek: '[afgelopen] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'over %s',
	        past : '%s geleden',
	        s : 'een paar seconden',
	        m : 'één minuut',
	        mm : '%d minuten',
	        h : 'één uur',
	        hh : '%d uur',
	        d : 'één dag',
	        dd : '%d dagen',
	        M : 'één maand',
	        MM : '%d maanden',
	        y : 'één jaar',
	        yy : '%d jaar'
	    },
	    ordinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Dutch (Belgium) [nl-be]
	//! author : Joris Röling : https://github.com/jorisroling
	//! author : Jacob Middag : https://github.com/middagj
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
	
	var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];
	var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
	
	var nlBe = moment.defineLocale('nl-be', {
	    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
	    monthsShort : function (m, format) {
	        if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	
	    monthsRegex: monthsRegex,
	    monthsShortRegex: monthsRegex,
	    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,
	    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
	
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
	    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
	    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[vandaag om] LT',
	        nextDay: '[morgen om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[gisteren om] LT',
	        lastWeek: '[afgelopen] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'over %s',
	        past : '%s geleden',
	        s : 'een paar seconden',
	        m : 'één minuut',
	        mm : '%d minuten',
	        h : 'één uur',
	        hh : '%d uur',
	        d : 'één dag',
	        dd : '%d dagen',
	        M : 'één maand',
	        MM : '%d maanden',
	        y : 'één jaar',
	        yy : '%d jaar'
	    },
	    ordinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nlBe;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Nynorsk [nn]
	//! author : https://github.com/mechuwind
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var nn = moment.defineLocale('nn', {
	    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
	    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),
	    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),
	    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] H:mm',
	        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[I dag klokka] LT',
	        nextDay: '[I morgon klokka] LT',
	        nextWeek: 'dddd [klokka] LT',
	        lastDay: '[I går klokka] LT',
	        lastWeek: '[Føregåande] dddd [klokka] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s sidan',
	        s : 'nokre sekund',
	        m : 'eit minutt',
	        mm : '%d minutt',
	        h : 'ein time',
	        hh : '%d timar',
	        d : 'ein dag',
	        dd : '%d dagar',
	        M : 'ein månad',
	        MM : '%d månader',
	        y : 'eit år',
	        yy : '%d år'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Punjabi (India) [pa-in]
	//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '੧',
	    '2': '੨',
	    '3': '੩',
	    '4': '੪',
	    '5': '੫',
	    '6': '੬',
	    '7': '੭',
	    '8': '੮',
	    '9': '੯',
	    '0': '੦'
	};
	var numberMap = {
	    '੧': '1',
	    '੨': '2',
	    '੩': '3',
	    '੪': '4',
	    '੫': '5',
	    '੬': '6',
	    '੭': '7',
	    '੮': '8',
	    '੯': '9',
	    '੦': '0'
	};
	
	var paIn = moment.defineLocale('pa-in', {
	    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.
	    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),
	    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),
	    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),
	    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
	    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm ਵਜੇ',
	        LTS : 'A h:mm:ss ਵਜੇ',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'
	    },
	    calendar : {
	        sameDay : '[ਅਜ] LT',
	        nextDay : '[ਕਲ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ਕਲ] LT',
	        lastWeek : '[ਪਿਛਲੇ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ਵਿੱਚ',
	        past : '%s ਪਿਛਲੇ',
	        s : 'ਕੁਝ ਸਕਿੰਟ',
	        m : 'ਇਕ ਮਿੰਟ',
	        mm : '%d ਮਿੰਟ',
	        h : 'ਇੱਕ ਘੰਟਾ',
	        hh : '%d ਘੰਟੇ',
	        d : 'ਇੱਕ ਦਿਨ',
	        dd : '%d ਦਿਨ',
	        M : 'ਇੱਕ ਮਹੀਨਾ',
	        MM : '%d ਮਹੀਨੇ',
	        y : 'ਇੱਕ ਸਾਲ',
	        yy : '%d ਸਾਲ'
	    },
	    preparse: function (string) {
	        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists
	    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.
	    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ਰਾਤ') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ਸਵੇਰ') {
	            return hour;
	        } else if (meridiem === 'ਦੁਪਹਿਰ') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'ਸ਼ਾਮ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ਰਾਤ';
	        } else if (hour < 10) {
	            return 'ਸਵੇਰ';
	        } else if (hour < 17) {
	            return 'ਦੁਪਹਿਰ';
	        } else if (hour < 20) {
	            return 'ਸ਼ਾਮ';
	        } else {
	            return 'ਰਾਤ';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return paIn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Polish [pl]
	//! author : Rafal Hirsz : https://github.com/evoL
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');
	var monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');
	function plural(n) {
	    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);
	}
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'minuta' : 'minutę';
	        case 'mm':
	            return result + (plural(number) ? 'minuty' : 'minut');
	        case 'h':
	            return withoutSuffix  ? 'godzina'  : 'godzinę';
	        case 'hh':
	            return result + (plural(number) ? 'godziny' : 'godzin');
	        case 'MM':
	            return result + (plural(number) ? 'miesiące' : 'miesięcy');
	        case 'yy':
	            return result + (plural(number) ? 'lata' : 'lat');
	    }
	}
	
	var pl = moment.defineLocale('pl', {
	    months : function (momentToFormat, format) {
	        if (format === '') {
	            // Hack: if format empty we know this is used to generate
	            // RegExp by moment. Give then back both valid forms of months
	            // in RegExp ready format.
	            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';
	        } else if (/D MMMM/.test(format)) {
	            return monthsSubjective[momentToFormat.month()];
	        } else {
	            return monthsNominative[momentToFormat.month()];
	        }
	    },
	    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),
	    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),
	    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),
	    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Dziś o] LT',
	        nextDay: '[Jutro o] LT',
	        nextWeek: '[W] dddd [o] LT',
	        lastDay: '[Wczoraj o] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[W zeszłą niedzielę o] LT';
	                case 3:
	                    return '[W zeszłą środę o] LT';
	                case 6:
	                    return '[W zeszłą sobotę o] LT';
	                default:
	                    return '[W zeszły] dddd [o] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : '%s temu',
	        s : 'kilka sekund',
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : '1 dzień',
	        dd : '%d dni',
	        M : 'miesiąc',
	        MM : translate,
	        y : 'rok',
	        yy : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return pl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Portuguese [pt]
	//! author : Jefferson : https://github.com/jalex79
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var pt = moment.defineLocale('pt', {
	    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
	    weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY HH:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hoje às] LT',
	        nextDay: '[Amanhã às] LT',
	        nextWeek: 'dddd [às] LT',
	        lastDay: '[Ontem às] LT',
	        lastWeek: function () {
	            return (this.day() === 0 || this.day() === 6) ?
	                '[Último] dddd [às] LT' : // Saturday + Sunday
	                '[Última] dddd [às] LT'; // Monday - Friday
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'em %s',
	        past : 'há %s',
	        s : 'segundos',
	        m : 'um minuto',
	        mm : '%d minutos',
	        h : 'uma hora',
	        hh : '%d horas',
	        d : 'um dia',
	        dd : '%d dias',
	        M : 'um mês',
	        MM : '%d meses',
	        y : 'um ano',
	        yy : '%d anos'
	    },
	    ordinalParse: /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return pt;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Portuguese (Brazil) [pt-br]
	//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ptBr = moment.defineLocale('pt-br', {
	    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
	    weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hoje às] LT',
	        nextDay: '[Amanhã às] LT',
	        nextWeek: 'dddd [às] LT',
	        lastDay: '[Ontem às] LT',
	        lastWeek: function () {
	            return (this.day() === 0 || this.day() === 6) ?
	                '[Último] dddd [às] LT' : // Saturday + Sunday
	                '[Última] dddd [às] LT'; // Monday - Friday
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'em %s',
	        past : '%s atrás',
	        s : 'poucos segundos',
	        m : 'um minuto',
	        mm : '%d minutos',
	        h : 'uma hora',
	        hh : '%d horas',
	        d : 'um dia',
	        dd : '%d dias',
	        M : 'um mês',
	        MM : '%d meses',
	        y : 'um ano',
	        yy : '%d anos'
	    },
	    ordinalParse: /\d{1,2}º/,
	    ordinal : '%dº'
	});
	
	return ptBr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Romanian [ro]
	//! author : Vlad Gurdiga : https://github.com/gurdiga
	//! author : Valentin Agachi : https://github.com/avaly
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	            'mm': 'minute',
	            'hh': 'ore',
	            'dd': 'zile',
	            'MM': 'luni',
	            'yy': 'ani'
	        },
	        separator = ' ';
	    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
	        separator = ' de ';
	    }
	    return number + separator + format[key];
	}
	
	var ro = moment.defineLocale('ro', {
	    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),
	    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),
	    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),
	    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay: '[azi la] LT',
	        nextDay: '[mâine la] LT',
	        nextWeek: 'dddd [la] LT',
	        lastDay: '[ieri la] LT',
	        lastWeek: '[fosta] dddd [la] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'peste %s',
	        past : '%s în urmă',
	        s : 'câteva secunde',
	        m : 'un minut',
	        mm : relativeTimeWithPlural,
	        h : 'o oră',
	        hh : relativeTimeWithPlural,
	        d : 'o zi',
	        dd : relativeTimeWithPlural,
	        M : 'o lună',
	        MM : relativeTimeWithPlural,
	        y : 'un an',
	        yy : relativeTimeWithPlural
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ro;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Russian [ru]
	//! author : Viktorminator : https://github.com/Viktorminator
	//! Author : Menelion Elensúle : https://github.com/Oire
	//! author : Коренберг Марк : https://github.com/socketpair
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
	        'hh': 'час_часа_часов',
	        'dd': 'день_дня_дней',
	        'MM': 'месяц_месяца_месяцев',
	        'yy': 'год_года_лет'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'минута' : 'минуту';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];
	
	// http://new.gramota.ru/spravka/rules/139-prop : § 103
	// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637
	// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753
	var ru = moment.defineLocale('ru', {
	    months : {
	        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),
	        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')
	    },
	    monthsShort : {
	        // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ?
	        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),
	        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')
	    },
	    weekdays : {
	        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
	        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),
	        isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/
	    },
	    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
	    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки
	    monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
	
	    // копия предыдущего
	    monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
	
	    // полные названия с падежами
	    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,
	
	    // Выражение, которое соотвествует только сокращённым формам
	    monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY г.',
	        LLL : 'D MMMM YYYY г., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY г., HH:mm'
	    },
	    calendar : {
	        sameDay: '[Сегодня в] LT',
	        nextDay: '[Завтра в] LT',
	        lastDay: '[Вчера в] LT',
	        nextWeek: function (now) {
	            if (now.week() !== this.week()) {
	                switch (this.day()) {
	                    case 0:
	                        return '[В следующее] dddd [в] LT';
	                    case 1:
	                    case 2:
	                    case 4:
	                        return '[В следующий] dddd [в] LT';
	                    case 3:
	                    case 5:
	                    case 6:
	                        return '[В следующую] dddd [в] LT';
	                }
	            } else {
	                if (this.day() === 2) {
	                    return '[Во] dddd [в] LT';
	                } else {
	                    return '[В] dddd [в] LT';
	                }
	            }
	        },
	        lastWeek: function (now) {
	            if (now.week() !== this.week()) {
	                switch (this.day()) {
	                    case 0:
	                        return '[В прошлое] dddd [в] LT';
	                    case 1:
	                    case 2:
	                    case 4:
	                        return '[В прошлый] dddd [в] LT';
	                    case 3:
	                    case 5:
	                    case 6:
	                        return '[В прошлую] dddd [в] LT';
	                }
	            } else {
	                if (this.day() === 2) {
	                    return '[Во] dddd [в] LT';
	                } else {
	                    return '[В] dddd [в] LT';
	                }
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'через %s',
	        past : '%s назад',
	        s : 'несколько секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : 'час',
	        hh : relativeTimeWithPlural,
	        d : 'день',
	        dd : relativeTimeWithPlural,
	        M : 'месяц',
	        MM : relativeTimeWithPlural,
	        y : 'год',
	        yy : relativeTimeWithPlural
	    },
	    meridiemParse: /ночи|утра|дня|вечера/i,
	    isPM : function (input) {
	        return /^(дня|вечера)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночи';
	        } else if (hour < 12) {
	            return 'утра';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечера';
	        }
	    },
	    ordinalParse: /\d{1,2}-(й|го|я)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	                return number + '-й';
	            case 'D':
	                return number + '-го';
	            case 'w':
	            case 'W':
	                return number + '-я';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ru;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Northern Sami [se]
	//! authors : Bård Rolstad Henriksen : https://github.com/karamell
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var se = moment.defineLocale('se', {
	    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),
	    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),
	    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),
	    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),
	    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'MMMM D. [b.] YYYY',
	        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',
	        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[otne ti] LT',
	        nextDay: '[ihttin ti] LT',
	        nextWeek: 'dddd [ti] LT',
	        lastDay: '[ikte ti] LT',
	        lastWeek: '[ovddit] dddd [ti] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s geažes',
	        past : 'maŋit %s',
	        s : 'moadde sekunddat',
	        m : 'okta minuhta',
	        mm : '%d minuhtat',
	        h : 'okta diimmu',
	        hh : '%d diimmut',
	        d : 'okta beaivi',
	        dd : '%d beaivvit',
	        M : 'okta mánnu',
	        MM : '%d mánut',
	        y : 'okta jahki',
	        yy : '%d jagit'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return se;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Sinhalese [si]
	//! author : Sampath Sitinamaluwa : https://github.com/sampathsris
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	/*jshint -W100*/
	var si = moment.defineLocale('si', {
	    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),
	    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),
	    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),
	    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),
	    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'a h:mm',
	        LTS : 'a h:mm:ss',
	        L : 'YYYY/MM/DD',
	        LL : 'YYYY MMMM D',
	        LLL : 'YYYY MMMM D, a h:mm',
	        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
	    },
	    calendar : {
	        sameDay : '[අද] LT[ට]',
	        nextDay : '[හෙට] LT[ට]',
	        nextWeek : 'dddd LT[ට]',
	        lastDay : '[ඊයේ] LT[ට]',
	        lastWeek : '[පසුගිය] dddd LT[ට]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%sකින්',
	        past : '%sකට පෙර',
	        s : 'තත්පර කිහිපය',
	        m : 'මිනිත්තුව',
	        mm : 'මිනිත්තු %d',
	        h : 'පැය',
	        hh : 'පැය %d',
	        d : 'දිනය',
	        dd : 'දින %d',
	        M : 'මාසය',
	        MM : 'මාස %d',
	        y : 'වසර',
	        yy : 'වසර %d'
	    },
	    ordinalParse: /\d{1,2} වැනි/,
	    ordinal : function (number) {
	        return number + ' වැනි';
	    },
	    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,
	    isPM : function (input) {
	        return input === 'ප.ව.' || input === 'පස් වරු';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'ප.ව.' : 'පස් වරු';
	        } else {
	            return isLower ? 'පෙ.ව.' : 'පෙර වරු';
	        }
	    }
	});
	
	return si;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Slovak [sk]
	//! author : Martin Minka : https://github.com/k2s
	//! based on work of petrbela : https://github.com/petrbela
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');
	var monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');
	function plural(n) {
	    return (n > 1) && (n < 5);
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':  // a few seconds / in a few seconds / a few seconds ago
	            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';
	        case 'm':  // a minute / in a minute / a minute ago
	            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');
	        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'minúty' : 'minút');
	            } else {
	                return result + 'minútami';
	            }
	            break;
	        case 'h':  // an hour / in an hour / an hour ago
	            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
	        case 'hh': // 9 hours / in 9 hours / 9 hours ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'hodiny' : 'hodín');
	            } else {
	                return result + 'hodinami';
	            }
	            break;
	        case 'd':  // a day / in a day / a day ago
	            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';
	        case 'dd': // 9 days / in 9 days / 9 days ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'dni' : 'dní');
	            } else {
	                return result + 'dňami';
	            }
	            break;
	        case 'M':  // a month / in a month / a month ago
	            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';
	        case 'MM': // 9 months / in 9 months / 9 months ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'mesiace' : 'mesiacov');
	            } else {
	                return result + 'mesiacmi';
	            }
	            break;
	        case 'y':  // a year / in a year / a year ago
	            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';
	        case 'yy': // 9 years / in 9 years / 9 years ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'roky' : 'rokov');
	            } else {
	                return result + 'rokmi';
	            }
	            break;
	    }
	}
	
	var sk = moment.defineLocale('sk', {
	    months : months,
	    monthsShort : monthsShort,
	    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),
	    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),
	    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
	    longDateFormat : {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay: '[dnes o] LT',
	        nextDay: '[zajtra o] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v nedeľu o] LT';
	                case 1:
	                case 2:
	                    return '[v] dddd [o] LT';
	                case 3:
	                    return '[v stredu o] LT';
	                case 4:
	                    return '[vo štvrtok o] LT';
	                case 5:
	                    return '[v piatok o] LT';
	                case 6:
	                    return '[v sobotu o] LT';
	            }
	        },
	        lastDay: '[včera o] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[minulú nedeľu o] LT';
	                case 1:
	                case 2:
	                    return '[minulý] dddd [o] LT';
	                case 3:
	                    return '[minulú stredu o] LT';
	                case 4:
	                case 5:
	                    return '[minulý] dddd [o] LT';
	                case 6:
	                    return '[minulú sobotu o] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : 'pred %s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Slovenian [sl]
	//! author : Robert Sedovšek : https://github.com/sedovsek
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':
	            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';
	        case 'm':
	            return withoutSuffix ? 'ena minuta' : 'eno minuto';
	        case 'mm':
	            if (number === 1) {
	                result += withoutSuffix ? 'minuta' : 'minuto';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'minute' : 'minutami';
	            } else {
	                result += withoutSuffix || isFuture ? 'minut' : 'minutami';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'ena ura' : 'eno uro';
	        case 'hh':
	            if (number === 1) {
	                result += withoutSuffix ? 'ura' : 'uro';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'uri' : 'urama';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'ure' : 'urami';
	            } else {
	                result += withoutSuffix || isFuture ? 'ur' : 'urami';
	            }
	            return result;
	        case 'd':
	            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';
	        case 'dd':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'dan' : 'dnem';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';
	            } else {
	                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';
	            }
	            return result;
	        case 'M':
	            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';
	        case 'MM':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';
	            } else {
	                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';
	            }
	            return result;
	        case 'y':
	            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';
	        case 'yy':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'leto' : 'letom';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'leti' : 'letoma';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'leta' : 'leti';
	            } else {
	                result += withoutSuffix || isFuture ? 'let' : 'leti';
	            }
	            return result;
	    }
	}
	
	var sl = moment.defineLocale('sl', {
	    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),
	    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),
	    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danes ob] LT',
	        nextDay  : '[jutri ob] LT',
	
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v] [nedeljo] [ob] LT';
	                case 3:
	                    return '[v] [sredo] [ob] LT';
	                case 6:
	                    return '[v] [soboto] [ob] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[v] dddd [ob] LT';
	            }
	        },
	        lastDay  : '[včeraj ob] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[prejšnjo] [nedeljo] [ob] LT';
	                case 3:
	                    return '[prejšnjo] [sredo] [ob] LT';
	                case 6:
	                    return '[prejšnjo] [soboto] [ob] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prejšnji] dddd [ob] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'čez %s',
	        past   : 'pred %s',
	        s      : processRelativeTime,
	        m      : processRelativeTime,
	        mm     : processRelativeTime,
	        h      : processRelativeTime,
	        hh     : processRelativeTime,
	        d      : processRelativeTime,
	        dd     : processRelativeTime,
	        M      : processRelativeTime,
	        MM     : processRelativeTime,
	        y      : processRelativeTime,
	        yy     : processRelativeTime
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Albanian [sq]
	//! author : Flakërim Ismani : https://github.com/flakerimi
	//! author : Menelion Elensúle : https://github.com/Oire
	//! author : Oerd Cukalla : https://github.com/oerd
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sq = moment.defineLocale('sq', {
	    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),
	    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),
	    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),
	    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),
	    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),
	    weekdaysParseExact : true,
	    meridiemParse: /PD|MD/,
	    isPM: function (input) {
	        return input.charAt(0) === 'M';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        return hours < 12 ? 'PD' : 'MD';
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Sot në] LT',
	        nextDay : '[Nesër në] LT',
	        nextWeek : 'dddd [në] LT',
	        lastDay : '[Dje në] LT',
	        lastWeek : 'dddd [e kaluar në] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'në %s',
	        past : '%s më parë',
	        s : 'disa sekonda',
	        m : 'një minutë',
	        mm : '%d minuta',
	        h : 'një orë',
	        hh : '%d orë',
	        d : 'një ditë',
	        dd : '%d ditë',
	        M : 'një muaj',
	        MM : '%d muaj',
	        y : 'një vit',
	        yy : '%d vite'
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sq;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Serbian [sr]
	//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['jedan minut', 'jedne minute'],
	        mm: ['minut', 'minute', 'minuta'],
	        h: ['jedan sat', 'jednog sata'],
	        hh: ['sat', 'sata', 'sati'],
	        dd: ['dan', 'dana', 'dana'],
	        MM: ['mesec', 'meseca', 'meseci'],
	        yy: ['godina', 'godine', 'godina']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var sr = moment.defineLocale('sr', {
	    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),
	    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[danas u] LT',
	        nextDay: '[sutra u] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedelju] [u] LT';
	                case 3:
	                    return '[u] [sredu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[juče u] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[prošle] [nedelje] [u] LT',
	                '[prošlog] [ponedeljka] [u] LT',
	                '[prošlog] [utorka] [u] LT',
	                '[prošle] [srede] [u] LT',
	                '[prošlog] [četvrtka] [u] LT',
	                '[prošlog] [petka] [u] LT',
	                '[prošle] [subote] [u] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'pre %s',
	        s      : 'nekoliko sekundi',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'dan',
	        dd     : translator.translate,
	        M      : 'mesec',
	        MM     : translator.translate,
	        y      : 'godinu',
	        yy     : translator.translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Serbian Cyrillic [sr-cyrl]
	//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['један минут', 'једне минуте'],
	        mm: ['минут', 'минуте', 'минута'],
	        h: ['један сат', 'једног сата'],
	        hh: ['сат', 'сата', 'сати'],
	        dd: ['дан', 'дана', 'дана'],
	        MM: ['месец', 'месеца', 'месеци'],
	        yy: ['година', 'године', 'година']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var srCyrl = moment.defineLocale('sr-cyrl', {
	    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),
	    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),
	    monthsParseExact: true,
	    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),
	    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),
	    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[данас у] LT',
	        nextDay: '[сутра у] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[у] [недељу] [у] LT';
	                case 3:
	                    return '[у] [среду] [у] LT';
	                case 6:
	                    return '[у] [суботу] [у] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[у] dddd [у] LT';
	            }
	        },
	        lastDay  : '[јуче у] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[прошле] [недеље] [у] LT',
	                '[прошлог] [понедељка] [у] LT',
	                '[прошлог] [уторка] [у] LT',
	                '[прошле] [среде] [у] LT',
	                '[прошлог] [четвртка] [у] LT',
	                '[прошлог] [петка] [у] LT',
	                '[прошле] [суботе] [у] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'за %s',
	        past   : 'пре %s',
	        s      : 'неколико секунди',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'дан',
	        dd     : translator.translate,
	        M      : 'месец',
	        MM     : translator.translate,
	        y      : 'годину',
	        yy     : translator.translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return srCyrl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : siSwati [ss]
	//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var ss = moment.defineLocale('ss', {
	    months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'),
	    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),
	    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),
	    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),
	    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Namuhla nga] LT',
	        nextDay : '[Kusasa nga] LT',
	        nextWeek : 'dddd [nga] LT',
	        lastDay : '[Itolo nga] LT',
	        lastWeek : 'dddd [leliphelile] [nga] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'nga %s',
	        past : 'wenteka nga %s',
	        s : 'emizuzwana lomcane',
	        m : 'umzuzu',
	        mm : '%d emizuzu',
	        h : 'lihora',
	        hh : '%d emahora',
	        d : 'lilanga',
	        dd : '%d emalanga',
	        M : 'inyanga',
	        MM : '%d tinyanga',
	        y : 'umnyaka',
	        yy : '%d iminyaka'
	    },
	    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'ekuseni';
	        } else if (hours < 15) {
	            return 'emini';
	        } else if (hours < 19) {
	            return 'entsambama';
	        } else {
	            return 'ebusuku';
	        }
	    },
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ekuseni') {
	            return hour;
	        } else if (meridiem === 'emini') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {
	            if (hour === 0) {
	                return 0;
	            }
	            return hour + 12;
	        }
	    },
	    ordinalParse: /\d{1,2}/,
	    ordinal : '%d',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ss;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Swedish [sv]
	//! author : Jens Alm : https://github.com/ulmus
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sv = moment.defineLocale('sv', {
	    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),
	    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),
	    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [kl.] HH:mm',
	        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Idag] LT',
	        nextDay: '[Imorgon] LT',
	        lastDay: '[Igår] LT',
	        nextWeek: '[På] dddd LT',
	        lastWeek: '[I] dddd[s] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : 'för %s sedan',
	        s : 'några sekunder',
	        m : 'en minut',
	        mm : '%d minuter',
	        h : 'en timme',
	        hh : '%d timmar',
	        d : 'en dag',
	        dd : '%d dagar',
	        M : 'en månad',
	        MM : '%d månader',
	        y : 'ett år',
	        yy : '%d år'
	    },
	    ordinalParse: /\d{1,2}(e|a)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'e' :
	            (b === 1) ? 'a' :
	            (b === 2) ? 'a' :
	            (b === 3) ? 'e' : 'e';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sv;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Swahili [sw]
	//! author : Fahad Kassim : https://github.com/fadsel
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sw = moment.defineLocale('sw', {
	    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),
	    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),
	    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[leo saa] LT',
	        nextDay : '[kesho saa] LT',
	        nextWeek : '[wiki ijayo] dddd [saat] LT',
	        lastDay : '[jana] LT',
	        lastWeek : '[wiki iliyopita] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s baadaye',
	        past : 'tokea %s',
	        s : 'hivi punde',
	        m : 'dakika moja',
	        mm : 'dakika %d',
	        h : 'saa limoja',
	        hh : 'masaa %d',
	        d : 'siku moja',
	        dd : 'masiku %d',
	        M : 'mwezi mmoja',
	        MM : 'miezi %d',
	        y : 'mwaka mmoja',
	        yy : 'miaka %d'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sw;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tamil [ta]
	//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '௧',
	    '2': '௨',
	    '3': '௩',
	    '4': '௪',
	    '5': '௫',
	    '6': '௬',
	    '7': '௭',
	    '8': '௮',
	    '9': '௯',
	    '0': '௦'
	};
	var numberMap = {
	    '௧': '1',
	    '௨': '2',
	    '௩': '3',
	    '௪': '4',
	    '௫': '5',
	    '௬': '6',
	    '௭': '7',
	    '௮': '8',
	    '௯': '9',
	    '௦': '0'
	};
	
	var ta = moment.defineLocale('ta', {
	    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
	    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
	    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),
	    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),
	    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, HH:mm',
	        LLLL : 'dddd, D MMMM YYYY, HH:mm'
	    },
	    calendar : {
	        sameDay : '[இன்று] LT',
	        nextDay : '[நாளை] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[நேற்று] LT',
	        lastWeek : '[கடந்த வாரம்] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s இல்',
	        past : '%s முன்',
	        s : 'ஒரு சில விநாடிகள்',
	        m : 'ஒரு நிமிடம்',
	        mm : '%d நிமிடங்கள்',
	        h : 'ஒரு மணி நேரம்',
	        hh : '%d மணி நேரம்',
	        d : 'ஒரு நாள்',
	        dd : '%d நாட்கள்',
	        M : 'ஒரு மாதம்',
	        MM : '%d மாதங்கள்',
	        y : 'ஒரு வருடம்',
	        yy : '%d ஆண்டுகள்'
	    },
	    ordinalParse: /\d{1,2}வது/,
	    ordinal : function (number) {
	        return number + 'வது';
	    },
	    preparse: function (string) {
	        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // refer http://ta.wikipedia.org/s/1er1
	    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 2) {
	            return ' யாமம்';
	        } else if (hour < 6) {
	            return ' வைகறை';  // வைகறை
	        } else if (hour < 10) {
	            return ' காலை'; // காலை
	        } else if (hour < 14) {
	            return ' நண்பகல்'; // நண்பகல்
	        } else if (hour < 18) {
	            return ' எற்பாடு'; // எற்பாடு
	        } else if (hour < 22) {
	            return ' மாலை'; // மாலை
	        } else {
	            return ' யாமம்';
	        }
	    },
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'யாமம்') {
	            return hour < 2 ? hour : hour + 12;
	        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {
	            return hour;
	        } else if (meridiem === 'நண்பகல்') {
	            return hour >= 10 ? hour : hour + 12;
	        } else {
	            return hour + 12;
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return ta;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Telugu [te]
	//! author : Krishna Chaitanya Thota : https://github.com/kcthota
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var te = moment.defineLocale('te', {
	    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),
	    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),
	    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),
	    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[నేడు] LT',
	        nextDay : '[రేపు] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[నిన్న] LT',
	        lastWeek : '[గత] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s లో',
	        past : '%s క్రితం',
	        s : 'కొన్ని క్షణాలు',
	        m : 'ఒక నిమిషం',
	        mm : '%d నిమిషాలు',
	        h : 'ఒక గంట',
	        hh : '%d గంటలు',
	        d : 'ఒక రోజు',
	        dd : '%d రోజులు',
	        M : 'ఒక నెల',
	        MM : '%d నెలలు',
	        y : 'ఒక సంవత్సరం',
	        yy : '%d సంవత్సరాలు'
	    },
	    ordinalParse : /\d{1,2}వ/,
	    ordinal : '%dవ',
	    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'రాత్రి') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ఉదయం') {
	            return hour;
	        } else if (meridiem === 'మధ్యాహ్నం') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'సాయంత్రం') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'రాత్రి';
	        } else if (hour < 10) {
	            return 'ఉదయం';
	        } else if (hour < 17) {
	            return 'మధ్యాహ్నం';
	        } else if (hour < 20) {
	            return 'సాయంత్రం';
	        } else {
	            return 'రాత్రి';
	        }
	    },
	    week : {
	        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.
	    }
	});
	
	return te;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tetun Dili (East Timor) [tet]
	//! author : Joshua Brooks : https://github.com/joshbrooks
	//! author : Onorio De J. Afonso : https://github.com/marobo
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tet = moment.defineLocale('tet', {
	    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),
	    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Ohin iha] LT',
	        nextDay: '[Aban iha] LT',
	        nextWeek: 'dddd [iha] LT',
	        lastDay: '[Horiseik iha] LT',
	        lastWeek: 'dddd [semana kotuk] [iha] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'iha %s',
	        past : '%s liuba',
	        s : 'minutu balun',
	        m : 'minutu ida',
	        mm : 'minutus %d',
	        h : 'horas ida',
	        hh : 'horas %d',
	        d : 'loron ida',
	        dd : 'loron %d',
	        M : 'fulan ida',
	        MM : 'fulan %d',
	        y : 'tinan ida',
	        yy : 'tinan %d'
	    },
	    ordinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tet;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Thai [th]
	//! author : Kridsada Thanabulpong : https://github.com/sirn
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var th = moment.defineLocale('th', {
	    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),
	    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),
	    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference
	    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'YYYY/MM/DD',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY เวลา H:mm',
	        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'
	    },
	    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
	    isPM: function (input) {
	        return input === 'หลังเที่ยง';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ก่อนเที่ยง';
	        } else {
	            return 'หลังเที่ยง';
	        }
	    },
	    calendar : {
	        sameDay : '[วันนี้ เวลา] LT',
	        nextDay : '[พรุ่งนี้ เวลา] LT',
	        nextWeek : 'dddd[หน้า เวลา] LT',
	        lastDay : '[เมื่อวานนี้ เวลา] LT',
	        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'อีก %s',
	        past : '%sที่แล้ว',
	        s : 'ไม่กี่วินาที',
	        m : '1 นาที',
	        mm : '%d นาที',
	        h : '1 ชั่วโมง',
	        hh : '%d ชั่วโมง',
	        d : '1 วัน',
	        dd : '%d วัน',
	        M : '1 เดือน',
	        MM : '%d เดือน',
	        y : '1 ปี',
	        yy : '%d ปี'
	    }
	});
	
	return th;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Tagalog (Philippines) [tl-ph]
	//! author : Dan Hagman : https://github.com/hagmandan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tlPh = moment.defineLocale('tl-ph', {
	    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),
	    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),
	    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),
	    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),
	    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'MM/D/YYYY',
	        LL : 'MMMM D, YYYY',
	        LLL : 'MMMM D, YYYY HH:mm',
	        LLLL : 'dddd, MMMM DD, YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: 'LT [ngayong araw]',
	        nextDay: '[Bukas ng] LT',
	        nextWeek: 'LT [sa susunod na] dddd',
	        lastDay: 'LT [kahapon]',
	        lastWeek: 'LT [noong nakaraang] dddd',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'sa loob ng %s',
	        past : '%s ang nakalipas',
	        s : 'ilang segundo',
	        m : 'isang minuto',
	        mm : '%d minuto',
	        h : 'isang oras',
	        hh : '%d oras',
	        d : 'isang araw',
	        dd : '%d araw',
	        M : 'isang buwan',
	        MM : '%d buwan',
	        y : 'isang taon',
	        yy : '%d taon'
	    },
	    ordinalParse: /\d{1,2}/,
	    ordinal : function (number) {
	        return number;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tlPh;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Klingon [tlh]
	//! author : Dominika Kruk : https://github.com/amaranthrose
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');
	
	function translateFuture(output) {
	    var time = output;
	    time = (output.indexOf('jaj') !== -1) ?
	    time.slice(0, -3) + 'leS' :
	    (output.indexOf('jar') !== -1) ?
	    time.slice(0, -3) + 'waQ' :
	    (output.indexOf('DIS') !== -1) ?
	    time.slice(0, -3) + 'nem' :
	    time + ' pIq';
	    return time;
	}
	
	function translatePast(output) {
	    var time = output;
	    time = (output.indexOf('jaj') !== -1) ?
	    time.slice(0, -3) + 'Hu’' :
	    (output.indexOf('jar') !== -1) ?
	    time.slice(0, -3) + 'wen' :
	    (output.indexOf('DIS') !== -1) ?
	    time.slice(0, -3) + 'ben' :
	    time + ' ret';
	    return time;
	}
	
	function translate(number, withoutSuffix, string, isFuture) {
	    var numberNoun = numberAsNoun(number);
	    switch (string) {
	        case 'mm':
	            return numberNoun + ' tup';
	        case 'hh':
	            return numberNoun + ' rep';
	        case 'dd':
	            return numberNoun + ' jaj';
	        case 'MM':
	            return numberNoun + ' jar';
	        case 'yy':
	            return numberNoun + ' DIS';
	    }
	}
	
	function numberAsNoun(number) {
	    var hundred = Math.floor((number % 1000) / 100),
	    ten = Math.floor((number % 100) / 10),
	    one = number % 10,
	    word = '';
	    if (hundred > 0) {
	        word += numbersNouns[hundred] + 'vatlh';
	    }
	    if (ten > 0) {
	        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';
	    }
	    if (one > 0) {
	        word += ((word !== '') ? ' ' : '') + numbersNouns[one];
	    }
	    return (word === '') ? 'pagh' : word;
	}
	
	var tlh = moment.defineLocale('tlh', {
	    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),
	    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[DaHjaj] LT',
	        nextDay: '[wa’leS] LT',
	        nextWeek: 'LLL',
	        lastDay: '[wa’Hu’] LT',
	        lastWeek: 'LLL',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : translateFuture,
	        past : translatePast,
	        s : 'puS lup',
	        m : 'wa’ tup',
	        mm : translate,
	        h : 'wa’ rep',
	        hh : translate,
	        d : 'wa’ jaj',
	        dd : translate,
	        M : 'wa’ jar',
	        MM : translate,
	        y : 'wa’ DIS',
	        yy : translate
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tlh;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Turkish [tr]
	//! authors : Erhan Gundogan : https://github.com/erhangundogan,
	//!           Burak Yiğit Kaya: https://github.com/BYK
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    1: '\'inci',
	    5: '\'inci',
	    8: '\'inci',
	    70: '\'inci',
	    80: '\'inci',
	    2: '\'nci',
	    7: '\'nci',
	    20: '\'nci',
	    50: '\'nci',
	    3: '\'üncü',
	    4: '\'üncü',
	    100: '\'üncü',
	    6: '\'ncı',
	    9: '\'uncu',
	    10: '\'uncu',
	    30: '\'uncu',
	    60: '\'ıncı',
	    90: '\'ıncı'
	};
	
	var tr = moment.defineLocale('tr', {
	    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),
	    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
	    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),
	    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
	    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[bugün saat] LT',
	        nextDay : '[yarın saat] LT',
	        nextWeek : '[haftaya] dddd [saat] LT',
	        lastDay : '[dün] LT',
	        lastWeek : '[geçen hafta] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s sonra',
	        past : '%s önce',
	        s : 'birkaç saniye',
	        m : 'bir dakika',
	        mm : '%d dakika',
	        h : 'bir saat',
	        hh : '%d saat',
	        d : 'bir gün',
	        dd : '%d gün',
	        M : 'bir ay',
	        MM : '%d ay',
	        y : 'bir yıl',
	        yy : '%d yıl'
	    },
	    ordinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,
	    ordinal : function (number) {
	        if (number === 0) {  // special case for zero
	            return number + '\'ıncı';
	        }
	        var a = number % 10,
	            b = number % 100 - a,
	            c = number >= 100 ? 100 : null;
	        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tr;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Talossan [tzl]
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v
	//! author : Iustì Canun
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.
	// This is currently too difficult (maybe even impossible) to add.
	var tzl = moment.defineLocale('tzl', {
	    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
	    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
	    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
	    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM [dallas] YYYY',
	        LLL : 'D. MMMM [dallas] YYYY HH.mm',
	        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'
	    },
	    meridiemParse: /d\'o|d\'a/i,
	    isPM : function (input) {
	        return 'd\'o' === input.toLowerCase();
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'd\'o' : 'D\'O';
	        } else {
	            return isLower ? 'd\'a' : 'D\'A';
	        }
	    },
	    calendar : {
	        sameDay : '[oxhi à] LT',
	        nextDay : '[demà à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[ieiri à] LT',
	        lastWeek : '[sür el] dddd [lasteu à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'osprei %s',
	        past : 'ja%s',
	        s : processRelativeTime,
	        m : processRelativeTime,
	        mm : processRelativeTime,
	        h : processRelativeTime,
	        hh : processRelativeTime,
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    ordinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's': ['viensas secunds', '\'iensas secunds'],
	        'm': ['\'n míut', '\'iens míut'],
	        'mm': [number + ' míuts', '' + number + ' míuts'],
	        'h': ['\'n þora', '\'iensa þora'],
	        'hh': [number + ' þoras', '' + number + ' þoras'],
	        'd': ['\'n ziua', '\'iensa ziua'],
	        'dd': [number + ' ziuas', '' + number + ' ziuas'],
	        'M': ['\'n mes', '\'iens mes'],
	        'MM': [number + ' mesen', '' + number + ' mesen'],
	        'y': ['\'n ar', '\'iens ar'],
	        'yy': [number + ' ars', '' + number + ' ars']
	    };
	    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);
	}
	
	return tzl;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Central Atlas Tamazight [tzm]
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tzm = moment.defineLocale('tzm', {
	    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
	    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
	    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
	        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',
	        nextWeek: 'dddd [ⴴ] LT',
	        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',
	        lastWeek: 'dddd [ⴴ] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',
	        past : 'ⵢⴰⵏ %s',
	        s : 'ⵉⵎⵉⴽ',
	        m : 'ⵎⵉⵏⵓⴺ',
	        mm : '%d ⵎⵉⵏⵓⴺ',
	        h : 'ⵙⴰⵄⴰ',
	        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',
	        d : 'ⴰⵙⵙ',
	        dd : '%d oⵙⵙⴰⵏ',
	        M : 'ⴰⵢoⵓⵔ',
	        MM : '%d ⵉⵢⵢⵉⵔⵏ',
	        y : 'ⴰⵙⴳⴰⵙ',
	        yy : '%d ⵉⵙⴳⴰⵙⵏ'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tzm;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Central Atlas Tamazight Latin [tzm-latn]
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tzmLatn = moment.defineLocale('tzm-latn', {
	    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
	    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
	    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[asdkh g] LT',
	        nextDay: '[aska g] LT',
	        nextWeek: 'dddd [g] LT',
	        lastDay: '[assant g] LT',
	        lastWeek: 'dddd [g] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'dadkh s yan %s',
	        past : 'yan %s',
	        s : 'imik',
	        m : 'minuḍ',
	        mm : '%d minuḍ',
	        h : 'saɛa',
	        hh : '%d tassaɛin',
	        d : 'ass',
	        dd : '%d ossan',
	        M : 'ayowr',
	        MM : '%d iyyirn',
	        y : 'asgas',
	        yy : '%d isgasn'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tzmLatn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Ukrainian [uk]
	//! author : zemlanin : https://github.com/zemlanin
	//! Author : Menelion Elensúle : https://github.com/Oire
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
	        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',
	        'dd': 'день_дні_днів',
	        'MM': 'місяць_місяці_місяців',
	        'yy': 'рік_роки_років'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'хвилина' : 'хвилину';
	    }
	    else if (key === 'h') {
	        return withoutSuffix ? 'година' : 'годину';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	function weekdaysCaseReplace(m, format) {
	    var weekdays = {
	        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
	        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
	        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
	    },
	    nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
	        'accusative' :
	        ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
	            'genitive' :
	            'nominative');
	    return weekdays[nounCase][m.day()];
	}
	function processHoursFunction(str) {
	    return function () {
	        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
	    };
	}
	
	var uk = moment.defineLocale('uk', {
	    months : {
	        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),
	        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')
	    },
	    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),
	    weekdays : weekdaysCaseReplace,
	    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY р.',
	        LLL : 'D MMMM YYYY р., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY р., HH:mm'
	    },
	    calendar : {
	        sameDay: processHoursFunction('[Сьогодні '),
	        nextDay: processHoursFunction('[Завтра '),
	        lastDay: processHoursFunction('[Вчора '),
	        nextWeek: processHoursFunction('[У] dddd ['),
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 5:
	                case 6:
	                    return processHoursFunction('[Минулої] dddd [').call(this);
	                case 1:
	                case 2:
	                case 4:
	                    return processHoursFunction('[Минулого] dddd [').call(this);
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'за %s',
	        past : '%s тому',
	        s : 'декілька секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : 'годину',
	        hh : relativeTimeWithPlural,
	        d : 'день',
	        dd : relativeTimeWithPlural,
	        M : 'місяць',
	        MM : relativeTimeWithPlural,
	        y : 'рік',
	        yy : relativeTimeWithPlural
	    },
	    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
	    meridiemParse: /ночі|ранку|дня|вечора/,
	    isPM: function (input) {
	        return /^(дня|вечора)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночі';
	        } else if (hour < 12) {
	            return 'ранку';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечора';
	        }
	    },
	    ordinalParse: /\d{1,2}-(й|го)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	            case 'w':
	            case 'W':
	                return number + '-й';
	            case 'D':
	                return number + '-го';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return uk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Uzbek [uz]
	//! author : Sardor Muminov : https://github.com/muminoff
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var uz = moment.defineLocale('uz', {
	    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),
	    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),
	    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),
	    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),
	    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'D MMMM YYYY, dddd HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бугун соат] LT [да]',
	        nextDay : '[Эртага] LT [да]',
	        nextWeek : 'dddd [куни соат] LT [да]',
	        lastDay : '[Кеча соат] LT [да]',
	        lastWeek : '[Утган] dddd [куни соат] LT [да]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'Якин %s ичида',
	        past : 'Бир неча %s олдин',
	        s : 'фурсат',
	        m : 'бир дакика',
	        mm : '%d дакика',
	        h : 'бир соат',
	        hh : '%d соат',
	        d : 'бир кун',
	        dd : '%d кун',
	        M : 'бир ой',
	        MM : '%d ой',
	        y : 'бир йил',
	        yy : '%d йил'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return uz;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Vietnamese [vi]
	//! author : Bang Nguyen : https://github.com/bangnk
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var vi = moment.defineLocale('vi', {
	    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),
	    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),
	    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
	    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
	    weekdaysParseExact : true,
	    meridiemParse: /sa|ch/i,
	    isPM : function (input) {
	        return /^ch$/i.test(input);
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower ? 'sa' : 'SA';
	        } else {
	            return isLower ? 'ch' : 'CH';
	        }
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM [năm] YYYY',
	        LLL : 'D MMMM [năm] YYYY HH:mm',
	        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
	        l : 'DD/M/YYYY',
	        ll : 'D MMM YYYY',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd, D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hôm nay lúc] LT',
	        nextDay: '[Ngày mai lúc] LT',
	        nextWeek: 'dddd [tuần tới lúc] LT',
	        lastDay: '[Hôm qua lúc] LT',
	        lastWeek: 'dddd [tuần rồi lúc] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s tới',
	        past : '%s trước',
	        s : 'vài giây',
	        m : 'một phút',
	        mm : '%d phút',
	        h : 'một giờ',
	        hh : '%d giờ',
	        d : 'một ngày',
	        dd : '%d ngày',
	        M : 'một tháng',
	        MM : '%d tháng',
	        y : 'một năm',
	        yy : '%d năm'
	    },
	    ordinalParse: /\d{1,2}/,
	    ordinal : function (number) {
	        return number;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return vi;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Pseudo [x-pseudo]
	//! author : Andrew Hood : https://github.com/andrewhood125
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var xPseudo = moment.defineLocale('x-pseudo', {
	    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),
	    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),
	    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),
	    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[T~ódá~ý át] LT',
	        nextDay : '[T~ómó~rró~w át] LT',
	        nextWeek : 'dddd [át] LT',
	        lastDay : '[Ý~ést~érdá~ý át] LT',
	        lastWeek : '[L~ást] dddd [át] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'í~ñ %s',
	        past : '%s á~gó',
	        s : 'á ~féw ~sécó~ñds',
	        m : 'á ~míñ~úté',
	        mm : '%d m~íñú~tés',
	        h : 'á~ñ hó~úr',
	        hh : '%d h~óúrs',
	        d : 'á ~dáý',
	        dd : '%d d~áýs',
	        M : 'á ~móñ~th',
	        MM : '%d m~óñt~hs',
	        y : 'á ~ýéár',
	        yy : '%d ý~éárs'
	    },
	    ordinalParse: /\d{1,2}(th|st|nd|rd)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return xPseudo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Yoruba Nigeria [yo]
	//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var yo = moment.defineLocale('yo', {
	    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),
	    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),
	    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),
	    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),
	    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Ònì ni] LT',
	        nextDay : '[Ọ̀la ni] LT',
	        nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT',
	        lastDay : '[Àna ni] LT',
	        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ní %s',
	        past : '%s kọjá',
	        s : 'ìsẹjú aayá die',
	        m : 'ìsẹjú kan',
	        mm : 'ìsẹjú %d',
	        h : 'wákati kan',
	        hh : 'wákati %d',
	        d : 'ọjọ́ kan',
	        dd : 'ọjọ́ %d',
	        M : 'osù kan',
	        MM : 'osù %d',
	        y : 'ọdún kan',
	        yy : 'ọdún %d'
	    },
	    ordinalParse : /ọjọ́\s\d{1,2}/,
	    ordinal : 'ọjọ́ %d',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return yo;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chinese (China) [zh-cn]
	//! author : suupic : https://github.com/suupic
	//! author : Zeno Zeng : https://github.com/zenozeng
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhCn = moment.defineLocale('zh-cn', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'Ah点mm分',
	        LTS : 'Ah点m分s秒',
	        L : 'YYYY-MM-DD',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日Ah点mm分',
	        LLLL : 'YYYY年MMMD日ddddAh点mm分',
	        l : 'YYYY-MM-DD',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日Ah点mm分',
	        llll : 'YYYY年MMMD日ddddAh点mm分'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' ||
	                meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        } else {
	            // '中午'
	            return hour >= 11 ? hour : hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : function () {
	            return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';
	        },
	        nextDay : function () {
	            return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';
	        },
	        lastDay : function () {
	            return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';
	        },
	        nextWeek : function () {
	            var startOfWeek, prefix;
	            startOfWeek = moment().startOf('week');
	            prefix = this.diff(startOfWeek, 'days') >= 7 ? '[下]' : '[本]';
	            return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
	        },
	        lastWeek : function () {
	            var startOfWeek, prefix;
	            startOfWeek = moment().startOf('week');
	            prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';
	            return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
	        },
	        sameElse : 'LL'
	    },
	    ordinalParse: /\d{1,2}(日|月|周)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd':
	            case 'D':
	            case 'DDD':
	                return number + '日';
	            case 'M':
	                return number + '月';
	            case 'w':
	            case 'W':
	                return number + '周';
	            default:
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s内',
	        past : '%s前',
	        s : '几秒',
	        m : '1 分钟',
	        mm : '%d 分钟',
	        h : '1 小时',
	        hh : '%d 小时',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 个月',
	        MM : '%d 个月',
	        y : '1 年',
	        yy : '%d 年'
	    },
	    week : {
	        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return zhCn;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chinese (Hong Kong) [zh-hk]
	//! author : Ben : https://github.com/ben-lin
	//! author : Chris Lam : https://github.com/hehachris
	//! author : Konstantin : https://github.com/skfd
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhHk = moment.defineLocale('zh-hk', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'Ah點mm分',
	        LTS : 'Ah點m分s秒',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日Ah點mm分',
	        LLLL : 'YYYY年MMMD日ddddAh點mm分',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日Ah點mm分',
	        llll : 'YYYY年MMMD日ddddAh點mm分'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '中午') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    ordinalParse: /\d{1,2}(日|月|週)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd' :
	            case 'D' :
	            case 'DDD' :
	                return number + '日';
	            case 'M' :
	                return number + '月';
	            case 'w' :
	            case 'W' :
	                return number + '週';
	            default :
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s內',
	        past : '%s前',
	        s : '幾秒',
	        m : '1 分鐘',
	        mm : '%d 分鐘',
	        h : '1 小時',
	        hh : '%d 小時',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 個月',
	        MM : '%d 個月',
	        y : '1 年',
	        yy : '%d 年'
	    }
	});
	
	return zhHk;
	
	})));


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

	//! moment.js locale configuration
	//! locale : Chinese (Taiwan) [zh-tw]
	//! author : Ben : https://github.com/ben-lin
	//! author : Chris Lam : https://github.com/hehachris
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(414)) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhTw = moment.defineLocale('zh-tw', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'Ah點mm分',
	        LTS : 'Ah點m分s秒',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日Ah點mm分',
	        LLLL : 'YYYY年MMMD日ddddAh點mm分',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日Ah點mm分',
	        llll : 'YYYY年MMMD日ddddAh點mm分'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '中午') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    ordinalParse: /\d{1,2}(日|月|週)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd' :
	            case 'D' :
	            case 'DDD' :
	                return number + '日';
	            case 'M' :
	                return number + '月';
	            case 'w' :
	            case 'W' :
	                return number + '週';
	            default :
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s內',
	        past : '%s前',
	        s : '幾秒',
	        m : '1 分鐘',
	        mm : '%d 分鐘',
	        h : '1 小時',
	        hh : '%d 小時',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 個月',
	        MM : '%d 個月',
	        y : '1 年',
	        yy : '%d 年'
	    }
	});
	
	return zhTw;
	
	})));


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

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(525);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// Prepare cssTransformation
	var transform;
	
	var options = {}
	options.transform = transform
	// add the styles to the DOM
	var update = __webpack_require__(527)(content, options);
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!../../css-loader/index.js!./handsontable.min.css", function() {
				var newContent = require("!!../../css-loader/index.js!./handsontable.min.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

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

	exports = module.exports = __webpack_require__(526)(false);
	// imports
	
	
	// module
	exports.push([module.id, "/*!\n * (The MIT License)\n * \n * Copyright (c) 2012-2014 Marcin Warpechowski\n * Copyright (c) 2015 Handsoncode sp. z o.o. <hello@handsoncode.net>\n * \n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * 'Software'), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n * \n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n * \n * Version: 0.34.5\n * Release date: 12/10/2017 (built at 12/10/2017 10:04:52)\n */.handsontable .table td,.handsontable .table th{border-top:none}.handsontable tr{background:#fff}.handsontable td{background-color:inherit}.handsontable .table caption+thead tr:first-child td,.handsontable .table caption+thead tr:first-child th,.handsontable .table colgroup+thead tr:first-child td,.handsontable .table colgroup+thead tr:first-child th,.handsontable .table thead:first-child tr:first-child td,.handsontable .table thead:first-child tr:first-child th{border-top:1px solid #ccc}.handsontable .table-bordered{border:0;border-collapse:separate}.handsontable .table-bordered td,.handsontable .table-bordered th{border-left:none}.handsontable .table-bordered td:first-child,.handsontable .table-bordered th:first-child{border-left:1px solid #ccc}.handsontable .table>tbody>tr>td,.handsontable .table>tbody>tr>th,.handsontable .table>tfoot>tr>td,.handsontable .table>tfoot>tr>th,.handsontable .table>thead>tr>td,.handsontable .table>thead>tr>th{line-height:21px;padding:0 4px}.col-lg-1.handsontable,.col-lg-2.handsontable,.col-lg-3.handsontable,.col-lg-4.handsontable,.col-lg-5.handsontable,.col-lg-6.handsontable,.col-lg-7.handsontable,.col-lg-8.handsontable,.col-lg-9.handsontable,.col-lg-10.handsontable,.col-lg-11.handsontable,.col-lg-12.handsontable,.col-md-1.handsontable,.col-md-2.handsontable,.col-md-3.handsontable,.col-md-4.handsontable,.col-md-5.handsontable,.col-md-6.handsontable,.col-md-7.handsontable,.col-md-8.handsontable,.col-md-9.handsontable .col-sm-1.handsontable,.col-md-10.handsontable,.col-md-11.handsontable,.col-md-12.handsontable,.col-sm-2.handsontable,.col-sm-3.handsontable,.col-sm-4.handsontable,.col-sm-5.handsontable,.col-sm-6.handsontable,.col-sm-7.handsontable,.col-sm-8.handsontable,.col-sm-9.handsontable .col-xs-1.handsontable,.col-sm-10.handsontable,.col-sm-11.handsontable,.col-sm-12.handsontable,.col-xs-2.handsontable,.col-xs-3.handsontable,.col-xs-4.handsontable,.col-xs-5.handsontable,.col-xs-6.handsontable,.col-xs-7.handsontable,.col-xs-8.handsontable,.col-xs-9.handsontable,.col-xs-10.handsontable,.col-xs-11.handsontable,.col-xs-12.handsontable{padding-left:0;padding-right:0}.handsontable .table-striped>tbody>tr:nth-of-type(2n){background-color:#fff}.handsontable{position:relative}.handsontable .hide{display:none}.handsontable .relative{position:relative}.handsontable.htAutoSize{visibility:hidden;left:-99000px;position:absolute;top:-99000px}.handsontable .wtHider{width:0}.handsontable .wtSpreader{position:relative;width:0;height:auto}.handsontable div,.handsontable input,.handsontable table,.handsontable tbody,.handsontable td,.handsontable textarea,.handsontable th,.handsontable thead{box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box}.handsontable input,.handsontable textarea{min-height:0}.handsontable table.htCore{border-collapse:separate;border-spacing:0;margin:0;border-width:0;table-layout:fixed;width:0;outline-width:0;max-width:none;max-height:none}.handsontable col,.handsontable col.rowHeader{width:50px}.handsontable td,.handsontable th{border-top-width:0;border-left-width:0;border-right:1px solid #ccc;border-bottom:1px solid #ccc;height:22px;empty-cells:show;line-height:21px;padding:0 4px;background-color:#fff;vertical-align:top;overflow:hidden;outline-width:0;white-space:pre-line;background-clip:padding-box}.handsontable td.htInvalid{background-color:#ff4c42!important}.handsontable td.htNoWrap{white-space:nowrap}.handsontable th:last-child{border-right:1px solid #ccc;border-bottom:1px solid #ccc}.handsontable th.htNoFrame,.handsontable th:first-child.htNoFrame,.handsontable tr:first-child th.htNoFrame{border-left-width:0;background-color:#fff;border-color:#fff}.handsontable .htNoFrame+td,.handsontable .htNoFrame+th,.handsontable.htRowHeaders thead tr th:nth-child(2),.handsontable td:first-of-type,.handsontable th:first-child,.handsontable th:nth-child(2){border-left:1px solid #ccc}.handsontable tr:first-child td,.handsontable tr:first-child th{border-top:1px solid #ccc}.ht_master:not(.innerBorderLeft):not(.emptyColumns)~.handsontable:not(.ht_clone_top) thead tr th:first-child,.ht_master:not(.innerBorderLeft):not(.emptyColumns)~.handsontable tbody tr th{border-right-width:0}.ht_master:not(.innerBorderTop) thead tr.lastChild th,.ht_master:not(.innerBorderTop) thead tr:last-child th,.ht_master:not(.innerBorderTop)~.handsontable thead tr.lastChild th,.ht_master:not(.innerBorderTop)~.handsontable thead tr:last-child th{border-bottom-width:0}.handsontable th{background-color:#f3f3f3;color:#222;text-align:center;font-weight:400;white-space:nowrap}.handsontable thead th{padding:0}.handsontable th.active{background-color:#ccc}.handsontable thead th .relative{padding:2px 4px}.handsontable tbody th.ht__highlight,.handsontable thead th.ht__highlight{background-color:#dcdcdc}.handsontable.ht__selection--columns thead th.ht__highlight,.handsontable.ht__selection--rows tbody th.ht__highlight{background-color:#8eb0e7;color:#000}#hot-display-license-info{font-size:9px;color:#323232;padding:5px 0 3px;font-family:Helvetica,Arial,sans-serif;text-align:left}.handsontable .manualColumnResizer{position:fixed;top:0;cursor:col-resize;z-index:6;width:5px;height:25px}.handsontable .manualRowResizer{position:fixed;left:0;cursor:row-resize;z-index:6;height:5px;width:50px}.handsontable .manualColumnResizer.active,.handsontable .manualColumnResizer:hover,.handsontable .manualRowResizer.active,.handsontable .manualRowResizer:hover{background-color:#aab}.handsontable .manualColumnResizerGuide{position:fixed;right:0;top:0;background-color:#aab;display:none;width:0;border-right:1px dashed #777;margin-left:5px}.handsontable .manualRowResizerGuide{position:fixed;left:0;bottom:0;background-color:#aab;display:none;height:0;border-bottom:1px dashed #777;margin-top:5px}.handsontable .manualColumnResizerGuide.active,.handsontable .manualRowResizerGuide.active{display:block;z-index:7}.handsontable .columnSorting{position:relative}.handsontable .columnSorting:hover{text-decoration:underline;cursor:pointer}.handsontable .columnSorting.ascending:after{content:\"\\25B2\";color:#5f5f5f;position:absolute;right:-15px}.handsontable .columnSorting.descending:after{content:\"\\25BC\";color:#5f5f5f;position:absolute;right:-15px}.handsontable .wtBorder{position:absolute;font-size:0}.handsontable .wtBorder.hidden{display:none!important}.handsontable td.area{background:linear-gradient(180deg,rgba(181,209,255,.34) 0,rgba(181,209,255,.34));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"#57b5d1ff\",endColorstr=\"#57b5d1ff\",GradientType=0);background-color:#fff}.handsontable .wtBorder.corner{font-size:0;cursor:crosshair}.handsontable .htBorder.htFillBorder{background:red;width:1px;height:1px}.handsontableInput{border:none;outline-width:0;margin:0;padding:1px 5px 0;font-family:inherit;line-height:21px;font-size:inherit;box-shadow:inset 0 0 0 2px #5292f7;resize:none;display:block;color:#000;border-radius:0;background-color:#fff}.handsontableInputHolder{position:absolute;top:0;left:0;z-index:1}.htSelectEditor{-webkit-appearance:menulist-button!important;position:absolute;width:auto}.handsontable .htDimmed{color:#777}.handsontable .htSubmenu{position:relative}.handsontable .htSubmenu :after{content:\"\\25B6\";color:#777;position:absolute;right:5px}.handsontable .htLeft{text-align:left}.handsontable .htCenter{text-align:center}.handsontable .htRight{text-align:right}.handsontable .htJustify{text-align:justify}.handsontable .htTop{vertical-align:top}.handsontable .htMiddle{vertical-align:middle}.handsontable .htBottom{vertical-align:bottom}.handsontable .htPlaceholder{color:#999}.handsontable .htAutocompleteArrow{float:right;font-size:10px;color:#eee;cursor:default;width:16px;text-align:center}.handsontable td .htAutocompleteArrow:hover{color:#777}.handsontable td.area .htAutocompleteArrow{color:#d3d3d3}.handsontable .htCheckboxRendererInput{display:inline-block;vertical-align:middle}.handsontable .htCheckboxRendererInput.noValue{opacity:.5}.handsontable .htCheckboxRendererLabel{cursor:pointer;display:inline-block;width:100%}@-webkit-keyframes a{0%{opacity:1}to{opacity:0}}@keyframes a{0%{opacity:1}to{opacity:0}}@-webkit-keyframes b{0%{opacity:0}to{opacity:1}}@keyframes b{0%{opacity:0}to{opacity:1}}.handsontable .handsontable.ht_clone_top .wtHider{padding:0 0 5px}.handsontable .autocompleteEditor.handsontable{padding-right:17px}.handsontable .autocompleteEditor.handsontable.htMacScroll{padding-right:15px}.handsontable.listbox{margin:0}.handsontable.listbox .ht_master table{border:1px solid #ccc;border-collapse:separate;background:#fff}.handsontable.listbox td,.handsontable.listbox th,.handsontable.listbox tr:first-child td,.handsontable.listbox tr:first-child th,.handsontable.listbox tr:last-child th{border-color:transparent}.handsontable.listbox td,.handsontable.listbox th{white-space:nowrap;text-overflow:ellipsis}.handsontable.listbox td.htDimmed{cursor:default;color:inherit;font-style:inherit}.handsontable.listbox .wtBorder{visibility:hidden}.handsontable.listbox tr:hover td,.handsontable.listbox tr td.current{background:#eee}.ht_clone_top{z-index:2}.ht_clone_left{z-index:3}.ht_clone_bottom_left_corner,.ht_clone_debug,.ht_clone_top_left_corner{z-index:4}.handsontable td.htSearchResult{background:#fcedd9;color:#583707}.htBordered{border-width:1px}.htBordered.htTopBorderSolid{border-top-style:solid;border-top-color:#000}.htBordered.htRightBorderSolid{border-right-style:solid;border-right-color:#000}.htBordered.htBottomBorderSolid{border-bottom-style:solid;border-bottom-color:#000}.htBordered.htLeftBorderSolid{border-left-style:solid;border-left-color:#000}.handsontable tbody tr th:nth-last-child(2){border-right:1px solid #ccc}.handsontable thead tr:nth-last-child(2) th.htGroupIndicatorContainer{border-bottom:1px solid #ccc;padding-bottom:5px}.ht_clone_top_left_corner thead tr th:nth-last-child(2){border-right:1px solid #ccc}.htCollapseButton{width:10px;height:10px;line-height:10px;text-align:center;border-radius:5px;border:1px solid #f3f3f3;box-shadow:1px 1px 3px rgba(0,0,0,.4);cursor:pointer;margin-bottom:3px;position:relative}.htCollapseButton:after{content:\"\";height:300%;width:1px;display:block;background:#ccc;margin-left:4px;position:absolute;bottom:10px}thead .htCollapseButton{right:5px;position:absolute;top:5px;background:#fff}thead .htCollapseButton:after{height:1px;width:700%;right:10px;top:4px}.handsontable tr th .htExpandButton{position:absolute;width:10px;height:10px;line-height:10px;text-align:center;border-radius:5px;border:1px solid #f3f3f3;box-shadow:1px 1px 3px rgba(0,0,0,.4);cursor:pointer;top:0;display:none}.handsontable thead tr th .htExpandButton{top:5px}.handsontable tr th .htExpandButton.clickable{display:block}.collapsibleIndicator{position:absolute;top:50%;transform:translateY(-50%);right:5px;border:1px solid #a6a6a6;line-height:10px;color:#222;border-radius:10px;font-size:10px;width:10px;height:10px;cursor:pointer;box-shadow:0 0 0 6px #eee;background:#eee}.handsontable col.hidden{width:0!important}.handsontable table tr th.lightRightBorder{border-right:1px solid #e6e6e6}.handsontable tr.hidden,.handsontable tr.hidden td,.handsontable tr.hidden th{display:none}.ht_clone_bottom,.ht_clone_left,.ht_clone_top,.ht_master{overflow:hidden}.ht_master .wtHolder{overflow:auto}.ht_clone_left .wtHolder{overflow-x:hidden;overflow-y:auto}.ht_clone_bottom .wtHolder,.ht_clone_top .wtHolder{overflow-x:auto;overflow-y:hidden}.wtDebugHidden{display:none}.wtDebugVisible{display:block;-webkit-animation-duration:.5s;-webkit-animation-name:c;animation-duration:.5s;animation-name:c}@keyframes c{0%{display:none;opacity:0}1%{display:block;opacity:0}to{display:block;opacity:1}}@-webkit-keyframes c{0%{display:none;opacity:0}1%{display:block;opacity:0}to{display:block;opacity:1}}.handsontable.mobile,.handsontable.mobile .wtHolder{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-overflow-scrolling:touch}.htMobileEditorContainer{display:none;position:absolute;top:0;width:70%;height:54pt;background:#f8f8f8;border-radius:20px;border:1px solid #ebebeb;z-index:8;box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-text-size-adjust:none}.topLeftSelectionHandle-HitArea:not(.ht_master .topLeftSelectionHandle-HitArea),.topLeftSelectionHandle:not(.ht_master .topLeftSelectionHandle){z-index:11}.bottomRightSelectionHandle,.bottomRightSelectionHandle-HitArea,.topLeftSelectionHandle,.topLeftSelectionHandle-HitArea{left:-10000px;top:-10000px}.htMobileEditorContainer.active{display:block}.htMobileEditorContainer .inputs{position:absolute;right:210pt;bottom:10pt;top:10pt;left:14px;height:34pt}.htMobileEditorContainer .inputs textarea{font-size:13pt;border:1px solid #a1a1a1;-webkit-appearance:none;box-shadow:none;position:absolute;left:14px;right:14px;top:0;bottom:0;padding:7pt}.htMobileEditorContainer .cellPointer{position:absolute;top:-13pt;height:0;width:0;left:30px;border-left:13pt solid transparent;border-right:13pt solid transparent;border-bottom:13pt solid #ebebeb}.htMobileEditorContainer .cellPointer.hidden{display:none}.htMobileEditorContainer .cellPointer:before{content:\"\";display:block;position:absolute;top:2px;height:0;width:0;left:-13pt;border-left:13pt solid transparent;border-right:13pt solid transparent;border-bottom:13pt solid #f8f8f8}.htMobileEditorContainer .moveHandle{position:absolute;top:10pt;left:5px;width:30px;bottom:0;cursor:move;z-index:11}.htMobileEditorContainer .moveHandle:after{content:\"..\\A..\\A..\\A..\";white-space:pre;line-height:10px;font-size:20pt;display:inline-block;margin-top:-8px;color:#ebebeb}.htMobileEditorContainer .positionControls{width:205pt;position:absolute;right:5pt;top:0;bottom:0}.htMobileEditorContainer .positionControls>div{width:50pt;height:100%;float:left}.htMobileEditorContainer .positionControls>div:after{content:\" \";display:block;width:15pt;height:15pt;text-align:center;line-height:50pt}.htMobileEditorContainer .downButton:after,.htMobileEditorContainer .leftButton:after,.htMobileEditorContainer .rightButton:after,.htMobileEditorContainer .upButton:after{transform-origin:5pt 5pt;-webkit-transform-origin:5pt 5pt;margin:21pt 0 0 21pt}.htMobileEditorContainer .leftButton:after{border-top:2px solid #288ffe;border-left:2px solid #288ffe;-webkit-transform:rotate(-45deg)}.htMobileEditorContainer .leftButton:active:after{border-color:#cfcfcf}.htMobileEditorContainer .rightButton:after{border-top:2px solid #288ffe;border-left:2px solid #288ffe;-webkit-transform:rotate(135deg)}.htMobileEditorContainer .rightButton:active:after{border-color:#cfcfcf}.htMobileEditorContainer .upButton:after{border-top:2px solid #288ffe;border-left:2px solid #288ffe;-webkit-transform:rotate(45deg)}.htMobileEditorContainer .upButton:active:after{border-color:#cfcfcf}.htMobileEditorContainer .downButton:after{border-top:2px solid #288ffe;border-left:2px solid #288ffe;-webkit-transform:rotate(225deg)}.htMobileEditorContainer .downButton:active:after{border-color:#cfcfcf}.handsontable.hide-tween{-webkit-animation:a .3s;animation:a .3s;animation-fill-mode:forwards;-webkit-animation-fill-mode:forwards}.handsontable.show-tween{-webkit-animation:b .3s;animation:b .3s;animation-fill-mode:forwards;-webkit-animation-fill-mode:forwards}.htCommentCell{position:relative}.htCommentCell:after{content:\"\";position:absolute;top:0;right:0;border-left:6px solid transparent;border-top:6px solid #000}.htComments{display:none;z-index:9;position:absolute}.htCommentTextArea{box-shadow:0 1px 3px rgba(0,0,0,.117647),0 1px 2px rgba(0,0,0,.239216);box-sizing:border-box;border:none;border-left:3px solid #ccc;background-color:#fff;width:215px;height:90px;font-size:12px;padding:5px;outline:0!important;-webkit-appearance:none}.htCommentTextArea:focus{box-shadow:0 1px 3px rgba(0,0,0,.117647),0 1px 2px rgba(0,0,0,.239216),inset 0 0 0 1px #5292f7;border-left:3px solid #5292f7}\n/*!\n * Handsontable ContextMenu\n */.htContextMenu{display:none;position:absolute;z-index:10}.htContextMenu .ht_clone_corner,.htContextMenu .ht_clone_debug,.htContextMenu .ht_clone_left,.htContextMenu .ht_clone_top{display:none}.htContextMenu table.htCore{border:1px solid #ccc;border-bottom-width:2px;border-right-width:2px}.htContextMenu .wtBorder{visibility:hidden}.htContextMenu table tbody tr td{background:#fff;border-width:0;padding:4px 6px 0;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.htContextMenu table tbody tr td:first-child{border:0}.htContextMenu table tbody tr td.htDimmed{font-style:normal;color:#323232}.htContextMenu table tbody tr td.current,.htContextMenu table tbody tr td.zeroclipboard-is-hover{background:#f3f3f3}.htContextMenu table tbody tr td.htSeparator{border-top:1px solid #bbb;height:0;padding:0;cursor:default}.htContextMenu table tbody tr td.htDisabled{color:#999;cursor:default}.htContextMenu table tbody tr td.htDisabled:hover{background:#fff;color:#999;cursor:default}.htContextMenu table tbody tr.htHidden{display:none}.htContextMenu table tbody tr td .htItemWrapper{margin-left:10px;margin-right:6px}.htContextMenu table tbody tr td div span.selected{margin-top:-2px;position:absolute;left:4px}.htContextMenu .ht_master .wtHolder{overflow:hidden}textarea#HandsontableCopyPaste{position:fixed!important;top:0!important;right:100%!important;overflow:hidden;opacity:0;outline:0 none!important}.htRowHeaders .ht_master.innerBorderLeft~.ht_clone_left td:first-of-type,.htRowHeaders .ht_master.innerBorderLeft~.ht_clone_top_left_corner th:nth-child(2){border-left:0 none}.handsontable.ht__manualColumnMove.after-selection--columns thead th.ht__highlight{cursor:move;cursor:-webkit-grab;cursor:grab}.handsontable.ht__manualColumnMove.on-moving--columns,.handsontable.ht__manualColumnMove.on-moving--columns thead th.ht__highlight{cursor:move;cursor:-webkit-grabbing;cursor:grabbing}.handsontable.ht__manualColumnMove.on-moving--columns .manualColumnResizer{display:none}.handsontable .ht__manualColumnMove--backlight,.handsontable .ht__manualColumnMove--guideline{position:absolute;height:100%;display:none}.handsontable .ht__manualColumnMove--guideline{background:#757575;width:2px;top:0;margin-left:-1px;z-index:5}.handsontable .ht__manualColumnMove--backlight{background:#343434;background:rgba(52,52,52,.25);display:none;z-index:5;pointer-events:none}.handsontable.on-moving--columns .ht__manualColumnMove--backlight,.handsontable.on-moving--columns.show-ui .ht__manualColumnMove--guideline{display:block}.handsontable .wtHider{position:relative}.handsontable.ht__manualRowMove.after-selection--rows tbody th.ht__highlight{cursor:move;cursor:-webkit-grab;cursor:grab}.handsontable.ht__manualRowMove.on-moving--rows,.handsontable.ht__manualRowMove.on-moving--rows tbody th.ht__highlight{cursor:move;cursor:-webkit-grabbing;cursor:grabbing}.handsontable.ht__manualRowMove.on-moving--rows .manualRowResizer{display:none}.handsontable .ht__manualRowMove--backlight,.handsontable .ht__manualRowMove--guideline{position:absolute;width:100%;display:none}.handsontable .ht__manualRowMove--guideline{background:#757575;height:2px;left:0;margin-top:-1px;z-index:5}.handsontable .ht__manualRowMove--backlight{background:#343434;background:rgba(52,52,52,.25);display:none;z-index:5;pointer-events:none}.handsontable.on-moving--rows .ht__manualRowMove--backlight,.handsontable.on-moving--rows.show-ui .ht__manualRowMove--guideline{display:block}", ""]);
	
	// exports


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

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	// css base code, injected by the css-loader
	module.exports = function(useSourceMap) {
		var list = [];
	
		// return the list of modules as css string
		list.toString = function toString() {
			return this.map(function (item) {
				var content = cssWithMappingToString(item, useSourceMap);
				if(item[2]) {
					return "@media " + item[2] + "{" + content + "}";
				} else {
					return content;
				}
			}).join("");
		};
	
		// import a list of modules into the list
		list.i = function(modules, mediaQuery) {
			if(typeof modules === "string")
				modules = [[null, modules, ""]];
			var alreadyImportedModules = {};
			for(var i = 0; i < this.length; i++) {
				var id = this[i][0];
				if(typeof id === "number")
					alreadyImportedModules[id] = true;
			}
			for(i = 0; i < modules.length; i++) {
				var item = modules[i];
				// skip already imported module
				// this implementation is not 100% perfect for weird media query combinations
				//  when a module is imported multiple times with different media queries.
				//  I hope this will never occur (Hey this way we have smaller bundles)
				if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
					if(mediaQuery && !item[2]) {
						item[2] = mediaQuery;
					} else if(mediaQuery) {
						item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
					}
					list.push(item);
				}
			}
		};
		return list;
	};
	
	function cssWithMappingToString(item, useSourceMap) {
		var content = item[1] || '';
		var cssMapping = item[3];
		if (!cssMapping) {
			return content;
		}
	
		if (useSourceMap && typeof btoa === 'function') {
			var sourceMapping = toComment(cssMapping);
			var sourceURLs = cssMapping.sources.map(function (source) {
				return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
			});
	
			return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
		}
	
		return [content].join('\n');
	}
	
	// Adapted from convert-source-map (MIT)
	function toComment(sourceMap) {
		// eslint-disable-next-line no-undef
		var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
		var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
	
		return '/*# ' + data + ' */';
	}


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

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	
	var stylesInDom = {};
	
	var	memoize = function (fn) {
		var memo;
	
		return function () {
			if (typeof memo === "undefined") memo = fn.apply(this, arguments);
			return memo;
		};
	};
	
	var isOldIE = memoize(function () {
		// Test for IE <= 9 as proposed by Browserhacks
		// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
		// Tests for existence of standard globals is to allow style-loader
		// to operate correctly into non-standard environments
		// @see https://github.com/webpack-contrib/style-loader/issues/177
		return window && document && document.all && !window.atob;
	});
	
	var getElement = (function (fn) {
		var memo = {};
	
		return function(selector) {
			if (typeof memo[selector] === "undefined") {
				memo[selector] = fn.call(this, selector);
			}
	
			return memo[selector]
		};
	})(function (target) {
		return document.querySelector(target)
	});
	
	var singleton = null;
	var	singletonCounter = 0;
	var	stylesInsertedAtTop = [];
	
	var	fixUrls = __webpack_require__(528);
	
	module.exports = function(list, options) {
		if (false) {
			if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
		}
	
		options = options || {};
	
		options.attrs = typeof options.attrs === "object" ? options.attrs : {};
	
		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
		// tags it will allow on a page
		if (!options.singleton) options.singleton = isOldIE();
	
		// By default, add <style> tags to the <head> element
		if (!options.insertInto) options.insertInto = "head";
	
		// By default, add <style> tags to the bottom of the target
		if (!options.insertAt) options.insertAt = "bottom";
	
		var styles = listToStyles(list, options);
	
		addStylesToDom(styles, options);
	
		return function update (newList) {
			var mayRemove = [];
	
			for (var i = 0; i < styles.length; i++) {
				var item = styles[i];
				var domStyle = stylesInDom[item.id];
	
				domStyle.refs--;
				mayRemove.push(domStyle);
			}
	
			if(newList) {
				var newStyles = listToStyles(newList, options);
				addStylesToDom(newStyles, options);
			}
	
			for (var i = 0; i < mayRemove.length; i++) {
				var domStyle = mayRemove[i];
	
				if(domStyle.refs === 0) {
					for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();
	
					delete stylesInDom[domStyle.id];
				}
			}
		};
	};
	
	function addStylesToDom (styles, options) {
		for (var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
	
			if(domStyle) {
				domStyle.refs++;
	
				for(var j = 0; j < domStyle.parts.length; j++) {
					domStyle.parts[j](item.parts[j]);
				}
	
				for(; j < item.parts.length; j++) {
					domStyle.parts.push(addStyle(item.parts[j], options));
				}
			} else {
				var parts = [];
	
				for(var j = 0; j < item.parts.length; j++) {
					parts.push(addStyle(item.parts[j], options));
				}
	
				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
			}
		}
	}
	
	function listToStyles (list, options) {
		var styles = [];
		var newStyles = {};
	
		for (var i = 0; i < list.length; i++) {
			var item = list[i];
			var id = options.base ? item[0] + options.base : item[0];
			var css = item[1];
			var media = item[2];
			var sourceMap = item[3];
			var part = {css: css, media: media, sourceMap: sourceMap};
	
			if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
			else newStyles[id].parts.push(part);
		}
	
		return styles;
	}
	
	function insertStyleElement (options, style) {
		var target = getElement(options.insertInto)
	
		if (!target) {
			throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
		}
	
		var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];
	
		if (options.insertAt === "top") {
			if (!lastStyleElementInsertedAtTop) {
				target.insertBefore(style, target.firstChild);
			} else if (lastStyleElementInsertedAtTop.nextSibling) {
				target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
			} else {
				target.appendChild(style);
			}
			stylesInsertedAtTop.push(style);
		} else if (options.insertAt === "bottom") {
			target.appendChild(style);
		} else {
			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
		}
	}
	
	function removeStyleElement (style) {
		if (style.parentNode === null) return false;
		style.parentNode.removeChild(style);
	
		var idx = stylesInsertedAtTop.indexOf(style);
		if(idx >= 0) {
			stylesInsertedAtTop.splice(idx, 1);
		}
	}
	
	function createStyleElement (options) {
		var style = document.createElement("style");
	
		options.attrs.type = "text/css";
	
		addAttrs(style, options.attrs);
		insertStyleElement(options, style);
	
		return style;
	}
	
	function createLinkElement (options) {
		var link = document.createElement("link");
	
		options.attrs.type = "text/css";
		options.attrs.rel = "stylesheet";
	
		addAttrs(link, options.attrs);
		insertStyleElement(options, link);
	
		return link;
	}
	
	function addAttrs (el, attrs) {
		Object.keys(attrs).forEach(function (key) {
			el.setAttribute(key, attrs[key]);
		});
	}
	
	function addStyle (obj, options) {
		var style, update, remove, result;
	
		// If a transform function was defined, run it on the css
		if (options.transform && obj.css) {
		    result = options.transform(obj.css);
	
		    if (result) {
		    	// If transform returns a value, use that instead of the original css.
		    	// This allows running runtime transformations on the css.
		    	obj.css = result;
		    } else {
		    	// If the transform function returns a falsy value, don't add this css.
		    	// This allows conditional loading of css
		    	return function() {
		    		// noop
		    	};
		    }
		}
	
		if (options.singleton) {
			var styleIndex = singletonCounter++;
	
			style = singleton || (singleton = createStyleElement(options));
	
			update = applyToSingletonTag.bind(null, style, styleIndex, false);
			remove = applyToSingletonTag.bind(null, style, styleIndex, true);
	
		} else if (
			obj.sourceMap &&
			typeof URL === "function" &&
			typeof URL.createObjectURL === "function" &&
			typeof URL.revokeObjectURL === "function" &&
			typeof Blob === "function" &&
			typeof btoa === "function"
		) {
			style = createLinkElement(options);
			update = updateLink.bind(null, style, options);
			remove = function () {
				removeStyleElement(style);
	
				if(style.href) URL.revokeObjectURL(style.href);
			};
		} else {
			style = createStyleElement(options);
			update = applyToTag.bind(null, style);
			remove = function () {
				removeStyleElement(style);
			};
		}
	
		update(obj);
	
		return function updateStyle (newObj) {
			if (newObj) {
				if (
					newObj.css === obj.css &&
					newObj.media === obj.media &&
					newObj.sourceMap === obj.sourceMap
				) {
					return;
				}
	
				update(obj = newObj);
			} else {
				remove();
			}
		};
	}
	
	var replaceText = (function () {
		var textStore = [];
	
		return function (index, replacement) {
			textStore[index] = replacement;
	
			return textStore.filter(Boolean).join('\n');
		};
	})();
	
	function applyToSingletonTag (style, index, remove, obj) {
		var css = remove ? "" : obj.css;
	
		if (style.styleSheet) {
			style.styleSheet.cssText = replaceText(index, css);
		} else {
			var cssNode = document.createTextNode(css);
			var childNodes = style.childNodes;
	
			if (childNodes[index]) style.removeChild(childNodes[index]);
	
			if (childNodes.length) {
				style.insertBefore(cssNode, childNodes[index]);
			} else {
				style.appendChild(cssNode);
			}
		}
	}
	
	function applyToTag (style, obj) {
		var css = obj.css;
		var media = obj.media;
	
		if(media) {
			style.setAttribute("media", media)
		}
	
		if(style.styleSheet) {
			style.styleSheet.cssText = css;
		} else {
			while(style.firstChild) {
				style.removeChild(style.firstChild);
			}
	
			style.appendChild(document.createTextNode(css));
		}
	}
	
	function updateLink (link, options, obj) {
		var css = obj.css;
		var sourceMap = obj.sourceMap;
	
		/*
			If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
			and there is no publicPath defined then lets turn convertToAbsoluteUrls
			on by default.  Otherwise default to the convertToAbsoluteUrls option
			directly
		*/
		var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;
	
		if (options.convertToAbsoluteUrls || autoFixUrls) {
			css = fixUrls(css);
		}
	
		if (sourceMap) {
			// http://stackoverflow.com/a/26603875
			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
		}
	
		var blob = new Blob([css], { type: "text/css" });
	
		var oldSrc = link.href;
	
		link.href = URL.createObjectURL(blob);
	
		if(oldSrc) URL.revokeObjectURL(oldSrc);
	}


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

	
	/**
	 * When source maps are enabled, `style-loader` uses a link element with a data-uri to
	 * embed the css on the page. This breaks all relative urls because now they are relative to a
	 * bundle instead of the current page.
	 *
	 * One solution is to only use full urls, but that may be impossible.
	 *
	 * Instead, this function "fixes" the relative urls to be absolute according to the current page location.
	 *
	 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
	 *
	 */
	
	module.exports = function (css) {
	  // get current location
	  var location = typeof window !== "undefined" && window.location;
	
	  if (!location) {
	    throw new Error("fixUrls requires window.location");
	  }
	
		// blank or null?
		if (!css || typeof css !== "string") {
		  return css;
	  }
	
	  var baseUrl = location.protocol + "//" + location.host;
	  var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");
	
		// convert each url(...)
		/*
		This regular expression is just a way to recursively match brackets within
		a string.
	
		 /url\s*\(  = Match on the word "url" with any whitespace after it and then a parens
		   (  = Start a capturing group
		     (?:  = Start a non-capturing group
		         [^)(]  = Match anything that isn't a parentheses
		         |  = OR
		         \(  = Match a start parentheses
		             (?:  = Start another non-capturing groups
		                 [^)(]+  = Match anything that isn't a parentheses
		                 |  = OR
		                 \(  = Match a start parentheses
		                     [^)(]*  = Match anything that isn't a parentheses
		                 \)  = Match a end parentheses
		             )  = End Group
	              *\) = Match anything and then a close parens
	          )  = Close non-capturing group
	          *  = Match anything
	       )  = Close capturing group
		 \)  = Match a close parens
	
		 /gi  = Get all matches, not the first.  Be case insensitive.
		 */
		var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
			// strip quotes (if they exist)
			var unquotedOrigUrl = origUrl
				.trim()
				.replace(/^"(.*)"$/, function(o, $1){ return $1; })
				.replace(/^'(.*)'$/, function(o, $1){ return $1; });
	
			// already a full url? no change
			if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(unquotedOrigUrl)) {
			  return fullMatch;
			}
	
			// convert the url to a full url
			var newUrl;
	
			if (unquotedOrigUrl.indexOf("//") === 0) {
			  	//TODO: should we add protocol?
				newUrl = unquotedOrigUrl;
			} else if (unquotedOrigUrl.indexOf("/") === 0) {
				// path should be relative to the base url
				newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
			} else {
				// path should be relative to current directory
				newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
			}
	
			// send back the fixed url(...)
			return "url(" + JSON.stringify(newUrl) + ")";
		});
	
		// send back the fixed css
		return fixedCss;
	};


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

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(530);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// Prepare cssTransformation
	var transform;
	
	var options = {}
	options.transform = transform
	// add the styles to the DOM
	var update = __webpack_require__(527)(content, options);
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!../../css-loader/index.js!./pikaday.css", function() {
				var newContent = require("!!../../css-loader/index.js!./pikaday.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

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

	exports = module.exports = __webpack_require__(526)(false);
	// imports
	
	
	// module
	exports.push([module.id, "@charset \"UTF-8\";\n\n/*!\n * Pikaday\n * Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/\n */\n\n.pika-single {\n    z-index: 9999;\n    display: block;\n    position: relative;\n    color: #333;\n    background: #fff;\n    border: 1px solid #ccc;\n    border-bottom-color: #bbb;\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n\n/*\nclear child float (pika-lendar), using the famous micro clearfix hack\nhttp://nicolasgallagher.com/micro-clearfix-hack/\n*/\n.pika-single:before,\n.pika-single:after {\n    content: \" \";\n    display: table;\n}\n.pika-single:after { clear: both }\n.pika-single { *zoom: 1 }\n\n.pika-single.is-hidden {\n    display: none;\n}\n\n.pika-single.is-bound {\n    position: absolute;\n    box-shadow: 0 5px 15px -5px rgba(0,0,0,.5);\n}\n\n.pika-lendar {\n    float: left;\n    width: 240px;\n    margin: 8px;\n}\n\n.pika-title {\n    position: relative;\n    text-align: center;\n}\n\n.pika-label {\n    display: inline-block;\n    *display: inline;\n    position: relative;\n    z-index: 9999;\n    overflow: hidden;\n    margin: 0;\n    padding: 5px 3px;\n    font-size: 14px;\n    line-height: 20px;\n    font-weight: bold;\n    background-color: #fff;\n}\n.pika-title select {\n    cursor: pointer;\n    position: absolute;\n    z-index: 9998;\n    margin: 0;\n    left: 0;\n    top: 5px;\n    filter: alpha(opacity=0);\n    opacity: 0;\n}\n\n.pika-prev,\n.pika-next {\n    display: block;\n    cursor: pointer;\n    position: relative;\n    outline: none;\n    border: 0;\n    padding: 0;\n    width: 20px;\n    height: 30px;\n    /* hide text using text-indent trick, using width value (it's enough) */\n    text-indent: 20px;\n    white-space: nowrap;\n    overflow: hidden;\n    background-color: transparent;\n    background-position: center center;\n    background-repeat: no-repeat;\n    background-size: 75% 75%;\n    opacity: .5;\n    *position: absolute;\n    *top: 0;\n}\n\n.pika-prev:hover,\n.pika-next:hover {\n    opacity: 1;\n}\n\n.pika-prev,\n.is-rtl .pika-next {\n    float: left;\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');\n    *left: 0;\n}\n\n.pika-next,\n.is-rtl .pika-prev {\n    float: right;\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');\n    *right: 0;\n}\n\n.pika-prev.is-disabled,\n.pika-next.is-disabled {\n    cursor: default;\n    opacity: .2;\n}\n\n.pika-select {\n    display: inline-block;\n    *display: inline;\n}\n\n.pika-table {\n    width: 100%;\n    border-collapse: collapse;\n    border-spacing: 0;\n    border: 0;\n}\n\n.pika-table th,\n.pika-table td {\n    width: 14.285714285714286%;\n    padding: 0;\n}\n\n.pika-table th {\n    color: #999;\n    font-size: 12px;\n    line-height: 25px;\n    font-weight: bold;\n    text-align: center;\n}\n\n.pika-button {\n    cursor: pointer;\n    display: block;\n    box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    outline: none;\n    border: 0;\n    margin: 0;\n    width: 100%;\n    padding: 5px;\n    color: #666;\n    font-size: 12px;\n    line-height: 15px;\n    text-align: right;\n    background: #f5f5f5;\n}\n\n.pika-week {\n    font-size: 11px;\n    color: #999;\n}\n\n.is-today .pika-button {\n    color: #33aaff;\n    font-weight: bold;\n}\n\n.is-selected .pika-button {\n    color: #fff;\n    font-weight: bold;\n    background: #33aaff;\n    box-shadow: inset 0 1px 3px #178fe5;\n    border-radius: 3px;\n}\n\n.is-inrange .pika-button {\n    background: #D5E9F7;\n}\n\n.is-startrange .pika-button {\n    color: #fff;\n    background: #6CB31D;\n    box-shadow: none;\n    border-radius: 3px;\n}\n\n.is-endrange .pika-button {\n    color: #fff;\n    background: #33aaff;\n    box-shadow: none;\n    border-radius: 3px;\n}\n\n.is-disabled .pika-button,\n.is-outside-current-month .pika-button {\n    pointer-events: none;\n    cursor: default;\n    color: #999;\n    opacity: .3;\n}\n\n.pika-button:hover {\n    color: #fff;\n    background: #ff8000;\n    box-shadow: none;\n    border-radius: 3px;\n}\n\n/* styling for abbr */\n.pika-table abbr {\n    border-bottom: none;\n    cursor: help;\n}\n\n", ""]);
	
	// exports


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

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(532);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// Prepare cssTransformation
	var transform;
	
	var options = {}
	options.transform = transform
	// add the styles to the DOM
	var update = __webpack_require__(527)(content, options);
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!../node_modules/css-loader/index.js!./custom.css", function() {
				var newContent = require("!!../node_modules/css-loader/index.js!./custom.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

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

	exports = module.exports = __webpack_require__(526)(false);
	// imports
	
	
	// module
	exports.push([module.id, ".wtHolder {\n  width: auto !important;\n  height: auto !important;\n}\n", ""]);
	
	// exports


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

	module.exports = {"name":"ipysheet","version":"0.1.0","description":"Spreadsheet in the Jupyter notebook","author":"Maarten A. Breddels","main":"src/index.js","repository":{"type":"git","url":"https://github.com/QuantStack/ipysheet.git"},"keywords":["jupyter","widgets","ipython","ipywidgets"],"scripts":{"prepublish":"webpack","test":"echo \"Error: no test specified\" && exit 1"},"jupyterlab":{"extension":"src/labplugin"},"devDependencies":{"@types/expect.js":"^0.3.29","@types/mocha":"^2.2.41","babel-core":"^6.26.0","babel-loader":"^6.0.0","babel-preset-es2015":"^6.24.1","chai":"^4.0.0","css-loader":"^0.28.4","eslint":"^4.15.0","json-loader":"^0.5.4","karma":"^1.6.0","karma-chai":"^0.1.0","karma-chrome-launcher":"^2.0.0","karma-mocha":"^1.3.0","karma-sourcemap-loader":"^0.3.7","karma-typescript":"^3.0.9","karma-typescript-es6-transform":"^1.0.3","karma-webpack":"^2.0.3","mocha":"^3.3.0","sinon":"^2.1.0","sinon-chai":"^2.11.0","style-loader":"^0.18.2","ts-loader":"~2.2.2","typescript":"~2.3.1","webpack":"^1.12.14"},"dependencies":{"@jupyter-widgets/base":"^1.0.1","@jupyter-widgets/jupyterlab-manager":"^0.28.0","css-loader":"^0.28.4","handsontable":"^0.34.1","lodash":"^4.17.4","style-loader":"^0.18.2","underscore":"^1.8.3"}}

/***/ })
/******/ ])});;
//# sourceMappingURL=index.js.map