react-date-picker
Version:
A carefully crafted date picker for React
1,589 lines (1,299 loc) • 506 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("React"));
else if(typeof define === 'function' && define.amd)
define(["React"], factory);
else if(typeof exports === 'object')
exports["DatePicker"] = factory(require("React"));
else
root["DatePicker"] = factory(root["React"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
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 = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}return target;
};
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 React = __webpack_require__(1);
var moment = __webpack_require__(2);
var assign = __webpack_require__(101);
var asConfig = __webpack_require__(102);
var MonthView = __webpack_require__(105);
var YearView = __webpack_require__(110);
var DecadeView = __webpack_require__(111);
var Header = __webpack_require__(112);
var toMoment = __webpack_require__(107);
var hasOwn = function hasOwn(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
};
var onEnter = __webpack_require__(108);
var Views = {
month: MonthView,
year: YearView,
decade: DecadeView
};
function emptyFn() {}
var DatePicker = React.createClass({
displayName: 'DatePicker',
propTypes: {
todayText: React.PropTypes.string,
gotoSelectedText: React.PropTypes.string,
renderFooter: React.PropTypes.func,
onChange: React.PropTypes.func,
date: React.PropTypes.any,
viewDate: React.PropTypes.any
},
getViewOrder: function getViewOrder() {
return this.props.viewOrder || ['month', 'year', 'decade'];
},
getDefaultProps: function getDefaultProps() {
var props = assign({}, asConfig(), {
highlightWeekends: false,
weekNumberName: '',
isDatePicker: true,
navOnDateClick: true,
highlightRangeOnMouseMove: true,
defaultStyle: {
boxSizing: 'border-box'
},
onRangeChange: function onRangeChange() {}
});
delete props.viewDate;
delete props.date;
return props;
},
getInitialState: function getInitialState() {
return {
view: this.props.defaultView,
viewDate: this.props.defaultViewDate,
defaultDate: this.props.defaultDate,
defaultRange: this.props.defaultRange
};
},
getViewName: function getViewName() {
var view = this.props.view != null ? this.props.view : this.state.view;
return view || 'month';
},
addViewIndex: function addViewIndex(amount) {
var viewName = this.getViewName();
var order = this.getViewOrder();
var index = order.indexOf(viewName);
index += amount;
return index % order.length;
},
getNextViewName: function getNextViewName() {
return this.getViewOrder()[this.addViewIndex(1)];
},
getPrevViewName: function getPrevViewName() {
return this.getViewOrder()[this.addViewIndex(-1)];
},
getView: function getView() {
var views = this.props.views || Views;
return views[this.getViewName()] || views.month;
},
getViewFactory: function getViewFactory() {
var view = this.getView();
if (React.createFactory && view && view.prototype && typeof view.prototype.render == 'function') {
view.__factory = view.__factory || React.createFactory(view);
view = view.__factory;
}
return view;
},
getViewDate: function getViewDate() {
var date = hasOwn(this.props, 'viewDate') ? this.props.viewDate : this.state.viewDate;
date = date || this.viewMoment || this.getDate() || new Date();
if (moment.isMoment(date)) {
//in order to strip the locale - the date picker may have had its locale changed
//between two render calls. If we don't strip this, moment(mom) returns a new moment
//with the locale of mom, which is not what we want
date = +date;
}
date = this.toMoment(date);
return date;
},
getDate: function getDate() {
var date;
if (hasOwn(this.props, 'date')) {
date = this.props.date;
} else {
date = this.state.defaultDate;
}
return date ? this.toMoment(date) : null;
},
getRange: function getRange() {
var _this = this;
var range;
if (hasOwn(this.props, 'range')) {
range = this.props.range;
} else if (this.state.defaultRange) {
range = this.state.defaultRange;
}
if (range) {
return range.map(function (r) {
return r ? _this.toMoment(r) : null;
}) || null;
} else {
return null;
}
},
render: function render() {
var props = this.p = assign({}, this.props);
this.toMoment = function (value, dateFormat) {
return toMoment(value, dateFormat || props.dateFormat, { locale: props.locale });
};
var view = this.getViewFactory();
props.date = this.getDate();
props.range = this.getRange();
var dateString = props.date == null ? '' : props.date.format(this.props.dateFormat);
props.viewDate = this.viewMoment = this.getViewDate();
props.locale = this.props.locale;
props.localeData = moment.localeData(props.locale);
props.renderDay = this.props.renderDay;
props.onRenderDay = this.props.onRenderDay;
// props.onChange = this.handleChange
// props.onSelect = this.handleSelect
var className = (this.props.className || '') + ' date-picker';
props.style = this.prepareStyle(props);
var viewProps = props;
var viewProps = asConfig(props);
viewProps.toMoment = this.toMoment;
viewProps.highlightWeekends = this.props.highlightWeekends;
viewProps.weekNumbers = this.props.weekNumbers;
viewProps.weekNumberName = this.props.weekNumberName;
viewProps.dateString = dateString;
viewProps.localeData = props.localeData;
viewProps.onSelect = this.handleSelect;
viewProps.onChange = this.handleChange;
viewProps.onWeekChange = this.props.onWeekChange;
viewProps.renderWeekNumber = this.props.renderWeekNumber;
viewProps.highlightRangeOnMouseMove = this.props.highlightRangeOnMouseMove;
viewProps.range = props.range;
return React.createElement('div', _extends({}, this.props, { className: className, style: props.style }), this.renderHeader(view, props), React.createElement('div', { className: 'dp-body', style: { flex: 1 } }, view(viewProps)), this.renderFooter(props));
},
prepareStyle: function prepareStyle(props) {
return assign({}, props.defaultStyle, props.style);
},
renderFooter: function renderFooter(props) {
if (this.props.hideFooter) {
return;
}
if (this.props.today) {
console.warn('Please use "todayText" prop instead of "today"!');
}
if (this.props.gotoSelected) {
console.warn('Please use "gotoSelectedText" prop instead of "gotoSelected"!');
}
var todayText = this.props.todayText || 'Today';
var gotoSelectedText = this.props.gotoSelectedText || 'Go to selected';
var footerProps = {
todayText: todayText,
gotoSelectedText: gotoSelectedText,
gotoToday: this.gotoNow,
gotoSelected: this.gotoSelected.bind(this, props),
date: props.date,
viewDate: props.viewDate
};
var result;
if (typeof this.props.footerFactory == 'function') {
result = this.props.footerFactory(footerProps);
}
if (result !== undefined) {
return result;
}
return React.createElement('div', { className: 'dp-footer' }, React.createElement('div', {
tabIndex: '1',
role: 'link',
className: 'dp-footer-today',
onClick: footerProps.gotoToday,
onKeyUp: onEnter(footerProps.gotoToday)
}, todayText), React.createElement('div', {
tabIndex: '1',
role: 'link',
className: 'dp-footer-selected',
onClick: footerProps.gotoSelected,
onKeyUp: onEnter(footerProps.gotoSelected)
}, gotoSelectedText));
},
gotoNow: function gotoNow() {
this.gotoDate(+new Date());
},
gotoSelected: function gotoSelected(props) {
this.gotoDate(props.date || +new Date());
},
gotoDate: function gotoDate(value) {
this.setView('month');
this.setViewDate(value);
},
getViewColspan: function getViewColspan() {
var map = {
month: 5,
year: 2,
decade: 2
};
return map[this.getViewName()];
},
renderHeader: function renderHeader(view, props) {
if (this.props.hideHeader) {
return;
}
props = props || this.props;
var viewDate = this.getViewDate();
var headerText = this.getView().getHeaderText(viewDate, props);
var colspan = this.getViewColspan();
var prev = this.props.navPrev;
var next = this.props.navNext;
return React.createElement(Header, {
prevText: prev,
nextText: next,
colspan: colspan,
onPrev: this.handleNavPrev,
onNext: this.handleNavNext,
onChange: this.handleViewChange
}, headerText);
},
handleRenderDay: function handleRenderDay(date) {
return (this.props.renderDay || emptyFn)(date) || [];
},
handleViewChange: function handleViewChange() {
this.setView(this.getNextViewName());
},
/**
* Use this method to set the view.
*
* @param {String} view 'month'/'year'/'decade'
*
* It calls onViewChange, and if the view is uncontrolled, also sets it is state,
* so the datepicker gets re-rendered view the new view
*
*/
setView: function setView(view) {
if (typeof this.props.onViewChange == 'function') {
this.props.onViewChange(view);
}
if (this.props.view == null) {
this.setState({
view: view
});
}
},
setViewDate: function setViewDate(moment) {
moment = this.toMoment(moment);
var fn = this.props.onViewDateChange;
if (typeof fn == 'function') {
var text = moment.format(this.props.dateFormat);
var view = this.getViewName();
fn(text, moment, view);
}
if (!hasOwn(this.props, 'viewDate')) {
this.setState({
viewDate: moment
});
}
},
getNext: function getNext() {
var current = this.getViewDate();
var toMoment = this.toMoment;
return {
month: function month() {
return toMoment(current).add(1, 'month');
},
year: function year() {
return toMoment(current).add(1, 'year');
},
decade: function decade() {
return toMoment(current).add(10, 'year');
}
}[this.getViewName()]();
},
getPrev: function getPrev() {
var current = this.getViewDate();
var toMoment = this.toMoment;
return {
month: function month() {
return toMoment(current).add(-1, 'month');
},
year: function year() {
return toMoment(current).add(-1, 'year');
},
decade: function decade() {
return toMoment(current).add(-10, 'year');
}
}[this.getViewName()]();
},
handleNavigation: function handleNavigation(direction, event) {
var viewMoment = direction == -1 ? this.getPrev() : this.getNext();
this.setViewDate(viewMoment);
if (typeof this.props.onNav === 'function') {
var text = viewMoment.format(this.props.dateFormat);
var view = this.getViewName();
this.props.onNav(text, viewMoment, view, direction, event);
}
},
handleNavPrev: function handleNavPrev(event) {
this.handleNavigation(-1, event);
},
handleNavNext: function handleNavNext(event) {
this.handleNavigation(1, event);
},
handleChange: function handleChange(date, event) {
date = this.toMoment(date);
if (this.props.navOnDateClick) {
var viewDate = this.toMoment(this.getViewDate());
//it's not enough to compare months, since the year can change as well
//
//also it's ok to hardcode the format here
var viewMonth = viewDate.format('YYYY-MM');
var dateMonth = date.format('YYYY-MM');
if (dateMonth > viewMonth) {
this.handleNavNext(event);
} else if (dateMonth < viewMonth) {
this.handleNavPrev(event);
}
}
var text = date.format(this.props.dateFormat);
if (!hasOwn(this.props, 'date')) {
this.setState({
defaultDate: text
});
}
;(this.props.onChange || emptyFn)(text, date, event);
if (this.p.range) {
this.handleRangeChange(date, event);
}
},
handleRangeChange: function handleRangeChange(mom) {
var _this2 = this;
var range = this.p.range;
if (range.length < 2) {
range = [].concat(_toConsumableArray(range), [mom]);
} else {
range = [mom];
}
range.sort(function (a, b) {
return a - b;
});
if (!this.props.range) {
this.setState({
defaultRange: range
});
}
var rangeText = range.map(function (date) {
return date.format(_this2.props.dateFormat);
});
this.props.onRangeChange(rangeText, range, event);
},
handleSelect: function handleSelect(date, event) {
var viewName = this.getViewName();
var property = {
decade: 'year',
year: 'month'
}[viewName];
var value = date.get(property);
var viewMoment = this.toMoment(this.getViewDate()).set(property, value);
var view = this.getPrevViewName();
this.setViewDate(viewMoment);
this.setView(view);
if (typeof this.props.onSelect === 'function') {
var text = viewMoment.format(this.props.dateFormat);
this.props.onSelect(text, viewMoment, view, event);
}
}
});
DatePicker.views = Views;
var PT = React.PropTypes;
DatePicker.propTypes = {
highlightWeekends: PT.bool,
/**
* Function to be called when user selects a date.
*
* Called with the following params:
*
* @param {String} dateText Date formatted as string
* @param {Moment} moment Moment.js instance
* @param {Event} event
*
* @type {Function}
*/
onChange: PT.func,
/**
* Function to be called when the user navigates to the next/prev month/year/decade
*
* Called with the following params:
*
* @param {String} dateText Date formatted as string
* @param {Moment} moment Moment.js instance
* @param {String} view The name of the current view (eg: "month")
* @param {Number} direction 1 or -1. 1 if the right arrow, to nav to next period was pressed. -1 if the left arrow, to nav to the prev period was pressed.
* @param {Event} event
*
* @type {Function}
*/
onNav: PT.func,
/**
* Function to be called when the user selects a year/month.
*
* Called with the following params:
*
* @param {String} dateText Date formatted as string
* @param {Moment} moment Moment.js instance
* @param {String} view The name of the view displayed after following the selection. For now, either "year" or "month"
*
* @type {Function}
*/
onSelect: PT.func,
/**
* A function that should return a React DOM for the day cell. The first param is the props object.
* You can use this to have full control over what gets rendered for a day.
*
* @param {Object} dayProps The props object passed to day rendering
*
* @type {Function}
*/
renderDay: PT.func,
/**
* A function that can manipulate the props object for a day, and SHOULD return a props object (a new one, or the same).
* Use this for CUSTOM DAY STYLING.
* You can use this to take full control over the styles/css classes/attributes applied to the day cell in the month view.
*
* @param {Object} dayProps
* @return {Object} dayProps
*
* @type {Function}
*/
onRenderDay: PT.func,
/******************************************/
/********** VIEW-related props ************/
/******************************************/
/**
* The default view to show in the picker. This is an uncontrolled prop.
* If none specified, the default view will be "month"
*
* @type {String}
*/
defaultView: PT.string,
/**
* The view to show in the picker. This is a CONTROLLED prop!
*
* When using this controlled prop, make sure you update it when `onViewChange` function is called
* if you want to navigate to another view, as expected.
*
* @type {String}
*/
view: PT.string,
/**
* A function to be called when navigating to another view date.
*
* Called with the following params:
*
* @param {String} dateText Date formatted as string
* @param {Moment} moment Moment.js instance
* @param {String} view the name of the view displayed after the navigation occurs.
*
* @type {Function}
*/
onViewDateChange: PT.func,
/**
* A function to be called when the view is changed.
* If you're using the controlled `view` prop, make sure you update the `view` prop in this function if you want to navigate to another view, as expected.
*
* @param {String} nextView One of "month", "year", "decade"
*
* @type {Function}
*/
onViewChange: PT.func,
/**
* Defaults to true. If specified as false, will not navigate to the date that was clicked, even if that date is in the prev/next month
* @type {Boolean}
*/
navOnDateClick: PT.bool,
highlightRangeOnMouseMove: PT.bool
};
module.exports = DatePicker;
/***/ },
/* 1 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(module) {//! moment.js
//! version : 2.11.2
//! 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 utils_hooks__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 Object.prototype.toString.call(input) === '[object Array]';
}
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 create_utc__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
};
}
function getParsingFlags(m) {
if (m._pf == null) {
m._pf = defaultParsingFlags();
}
return m._pf;
}
function valid__isValid(m) {
if (m._isValid == null) {
var flags = getParsingFlags(m);
m._isValid = !isNaN(m._d.getTime()) &&
flags.overflow < 0 &&
!flags.empty &&
!flags.invalidMonth &&
!flags.invalidWeekday &&
!flags.nullInput &&
!flags.invalidFormat &&
!flags.userInvalidated;
if (m._strict) {
m._isValid = m._isValid &&
flags.charsLeftOver === 0 &&
flags.unusedTokens.length === 0 &&
flags.bigHour === undefined;
}
}
return m._isValid;
}
function valid__createInvalid (flags) {
var m = create_utc__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 = utils_hooks__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);
// Prevent infinite loop in case updateOffset creates new moment
// objects.
if (updateInProgress === false) {
updateInProgress = true;
utils_hooks__hooks.updateOffset(this);
updateInProgress = false;
}
}
function isMoment (obj) {
return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
}
function absFloor (number) {
if (number < 0) {
return Math.ceil(number);
} 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 Locale() {
}
// internal storage for locale config files
var locales = {};
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__(4)("./" + name);
// because defineLocale currently also sets the global locale, we
// want to undo that for lazy loaded locales
locale_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 locale_locales__getSetGlobalLocale (key, values) {
var data;
if (key) {
if (isUndefined(values)) {
data = locale_locales__getLocale(key);
}
else {
data = defineLocale(key, values);
}
if (data) {
// moment.duration._locale = moment._locale = data;
globalLocale = data;
}
}
return globalLocale._abbr;
}
function defineLocale (name, values) {
if (values !== null) {
values.abbr = name;
locales[name] = locales[name] || new Locale();
locales[name].set(values);
// backwards compat for now: also set the locale
locale_locales__getSetGlobalLocale(name);
return locales[name];
} else {
// useful for testing
delete locales[name];
return null;
}
}
// returns locale data
function locale_locales__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);
}
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;
}
function isFunction(input) {
return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
}
function makeGetSet (unit, keepTime) {
return function (value) {
if (value != null) {
get_set__set(this, unit, value);
utils_hooks__hooks.updateOffset(this, keepTime);
return this;
} else {
return get_set__get(this, unit);
}
};
}
function get_set__get (mom, unit) {
return mom.isValid() ?
mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
}
function get_set__set (mom, unit, value) {
if (mom.isValid()) {
mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
}
}
// MOMENTS
function getSet (units, value) {
var unit;
if (typeof units === 'object') {
for (unit in units) {
this.set(unit, units[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?|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 = '';
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 (typeof callback === 'number') {
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;
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');
// 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) {
return isArray(this._months) ? this._months[m.month()] :
this._months[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) {
return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
}
function localeMonthsParse (monthName, format, strict) {
var i, mom, regex;
if (!this._monthsParse) {
this._monthsParse = [];
this._longMonthsParse = [];
this._shortMonthsParse = [];
}
for (i = 0; i < 12; i++) {
// make the regex if we don't have it already
mom = create_utc__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;
}
// TODO: Move this out of here!
if (typeof value === 'string') {
value = mom.localeData().monthsParse(value);
// TODO: Another silent failure?
if (typeof value !== 'number') {
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);
utils_hooks__hooks.updateOffset(this, true);
return this;
} else {
return get_set__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 {
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 {
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 = create_utc__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]);
mixedPieces[i] = regexEscape(mixedPieces[i]);
}
this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
this._monthsShortRegex = this._monthsRegex;
this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')$', 'i');
this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')$', 'i');
}
function 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;
}
function warn(msg) {
if (utils_hooks__hooks.suppressDeprecationWarnings === false &&
(typeof console !== 'undefined') && console.warn) {
console.warn('Deprecation warning: ' + msg);
}
}
function deprecate(msg, fn) {
var firstTime = true;
return extend(function () {
if (firstTime) {
warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
firstTime = false;
}
return fn.apply(this, arguments);
}, fn);
}
var deprecations = {};
function deprecateSimple(name, msg) {
if (!deprecations[name]) {
warn(msg);
deprecations[name] = true;
}
}
utils_hooks__hooks.suppressDeprecationWarnings = false;
// 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| )