You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cmda.apache.org by xi...@apache.org on 2015/10/29 23:56:25 UTC
[2/9] incubator-cmda git commit: Update ApacheCMDA-Frontend with
KnowledgeGraph
http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/ca952ad9/ApacheCMDA-Frontend/public/javascripts/vis.js
----------------------------------------------------------------------
diff --git a/ApacheCMDA-Frontend/public/javascripts/vis.js b/ApacheCMDA-Frontend/public/javascripts/vis.js
new file mode 100644
index 0000000..3388fc4
--- /dev/null
+++ b/ApacheCMDA-Frontend/public/javascripts/vis.js
@@ -0,0 +1,43387 @@
+/**
+ * vis.js
+ * https://github.com/almende/vis
+ *
+ * A dynamic, browser-based visualization library.
+ *
+ * @version 4.9.0
+ * @date 2015-10-01
+ *
+ * @license
+ * Copyright (C) 2011-2015 Almende B.V, http://almende.com
+ *
+ * Vis.js is dual licensed under both
+ *
+ * * The Apache 2.0 License
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * and
+ *
+ * * The MIT License
+ * http://opensource.org/licenses/MIT
+ *
+ * Vis.js may be distributed under either license.
+ */
+
+"use strict";
+
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory();
+ else if(typeof define === 'function' && define.amd)
+ define([], factory);
+ else if(typeof exports === 'object')
+ exports["vis"] = factory();
+ else
+ root["vis"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId])
+/******/ return installedModules[moduleId].exports;
+
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ 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__) {
+
+ // utils
+ 'use strict';
+
+ exports.util = __webpack_require__(1);
+ exports.DOMutil = __webpack_require__(7);
+
+ // data
+ exports.DataSet = __webpack_require__(8);
+ exports.DataView = __webpack_require__(10);
+ exports.Queue = __webpack_require__(9);
+
+ // Graph3d
+ exports.Graph3d = __webpack_require__(11);
+ exports.graph3d = {
+ Camera: __webpack_require__(15),
+ Filter: __webpack_require__(16),
+ Point2d: __webpack_require__(14),
+ Point3d: __webpack_require__(13),
+ Slider: __webpack_require__(17),
+ StepNumber: __webpack_require__(18)
+ };
+
+ // Timeline
+ exports.Timeline = __webpack_require__(19);
+ exports.Graph2d = __webpack_require__(49);
+ exports.timeline = {
+ DateUtil: __webpack_require__(27),
+ DataStep: __webpack_require__(52),
+ Range: __webpack_require__(24),
+ stack: __webpack_require__(32),
+ TimeStep: __webpack_require__(30),
+
+ components: {
+ items: {
+ Item: __webpack_require__(34),
+ BackgroundItem: __webpack_require__(38),
+ BoxItem: __webpack_require__(36),
+ PointItem: __webpack_require__(37),
+ RangeItem: __webpack_require__(33)
+ },
+
+ Component: __webpack_require__(26),
+ CurrentTime: __webpack_require__(44),
+ CustomTime: __webpack_require__(42),
+ DataAxis: __webpack_require__(51),
+ GraphGroup: __webpack_require__(53),
+ Group: __webpack_require__(31),
+ BackgroundGroup: __webpack_require__(35),
+ ItemSet: __webpack_require__(29),
+ Legend: __webpack_require__(57),
+ LineGraph: __webpack_require__(50),
+ TimeAxis: __webpack_require__(39)
+ }
+ };
+
+ // Network
+ exports.Network = __webpack_require__(59);
+ exports.network = {
+ Images: __webpack_require__(117),
+ dotparser: __webpack_require__(115),
+ gephiParser: __webpack_require__(116),
+ allOptions: __webpack_require__(111)
+ };
+ exports.network.convertDot = function (input) {
+ return exports.network.dotparser.DOTToGraph(input);
+ };
+ exports.network.convertGephi = function (input, options) {
+ return exports.network.gephiParser.parseGephi(input, options);
+ };
+
+ // bundled external libraries
+ exports.moment = __webpack_require__(2);
+ exports.Hammer = __webpack_require__(20);
+ exports.keycharm = __webpack_require__(41);
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+ // utility functions
+
+ // first check if moment.js is already loaded in the browser window, if so,
+ // use this instance. Else, load via commonjs.
+
+ 'use strict';
+
+ var moment = __webpack_require__(2);
+ var uuid = __webpack_require__(6);
+
+ /**
+ * Test whether given object is a number
+ * @param {*} object
+ * @return {Boolean} isNumber
+ */
+ exports.isNumber = function (object) {
+ return object instanceof Number || typeof object == 'number';
+ };
+
+ /**
+ * Remove everything in the DOM object
+ * @param DOMobject
+ */
+ exports.recursiveDOMDelete = function (DOMobject) {
+ if (DOMobject) {
+ while (DOMobject.hasChildNodes() === true) {
+ exports.recursiveDOMDelete(DOMobject.firstChild);
+ DOMobject.removeChild(DOMobject.firstChild);
+ }
+ }
+ };
+
+ /**
+ * this function gives you a range between 0 and 1 based on the min and max values in the set, the total sum of all values and the current value.
+ *
+ * @param min
+ * @param max
+ * @param total
+ * @param value
+ * @returns {number}
+ */
+ exports.giveRange = function (min, max, total, value) {
+ if (max == min) {
+ return 0.5;
+ } else {
+ var scale = 1 / (max - min);
+ return Math.max(0, (value - min) * scale);
+ }
+ };
+
+ /**
+ * Test whether given object is a string
+ * @param {*} object
+ * @return {Boolean} isString
+ */
+ exports.isString = function (object) {
+ return object instanceof String || typeof object == 'string';
+ };
+
+ /**
+ * Test whether given object is a Date, or a String containing a Date
+ * @param {Date | String} object
+ * @return {Boolean} isDate
+ */
+ exports.isDate = function (object) {
+ if (object instanceof Date) {
+ return true;
+ } else if (exports.isString(object)) {
+ // test whether this string contains a date
+ var match = ASPDateRegex.exec(object);
+ if (match) {
+ return true;
+ } else if (!isNaN(Date.parse(object))) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ /**
+ * Create a semi UUID
+ * source: http://stackoverflow.com/a/105074/1262753
+ * @return {String} uuid
+ */
+ exports.randomUUID = function () {
+ return uuid.v4();
+ };
+
+ /**
+ * assign all keys of an object that are not nested objects to a certain value (used for color objects).
+ * @param obj
+ * @param value
+ */
+ exports.assignAllKeys = function (obj, value) {
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ if (typeof obj[prop] !== 'object') {
+ obj[prop] = value;
+ }
+ }
+ }
+ };
+
+ /**
+ * Fill an object with a possibly partially defined other object. Only copies values if the a object has an object requiring values.
+ * That means an object is not created on a property if only the b object has it.
+ * @param obj
+ * @param value
+ */
+ exports.fillIfDefined = function (a, b) {
+ var allowDeletion = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
+
+ for (var prop in a) {
+ if (b[prop] !== undefined) {
+ if (typeof b[prop] !== 'object') {
+ if ((b[prop] === undefined || b[prop] === null) && a[prop] !== undefined && allowDeletion === true) {
+ delete a[prop];
+ } else {
+ a[prop] = b[prop];
+ }
+ } else {
+ if (typeof a[prop] === 'object') {
+ exports.fillIfDefined(a[prop], b[prop], allowDeletion);
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Extend object a with the properties of object b or a series of objects
+ * Only properties with defined values are copied
+ * @param {Object} a
+ * @param {... Object} b
+ * @return {Object} a
+ */
+ exports.protoExtend = function (a, b) {
+ for (var i = 1; i < arguments.length; i++) {
+ var other = arguments[i];
+ for (var prop in other) {
+ a[prop] = other[prop];
+ }
+ }
+ return a;
+ };
+
+ /**
+ * Extend object a with the properties of object b or a series of objects
+ * Only properties with defined values are copied
+ * @param {Object} a
+ * @param {... Object} b
+ * @return {Object} a
+ */
+ exports.extend = function (a, b) {
+ for (var i = 1; i < arguments.length; i++) {
+ var other = arguments[i];
+ for (var prop in other) {
+ if (other.hasOwnProperty(prop)) {
+ a[prop] = other[prop];
+ }
+ }
+ }
+ return a;
+ };
+
+ /**
+ * Extend object a with selected properties of object b or a series of objects
+ * Only properties with defined values are copied
+ * @param {Array.<String>} props
+ * @param {Object} a
+ * @param {Object} b
+ * @return {Object} a
+ */
+ exports.selectiveExtend = function (props, a, b) {
+ if (!Array.isArray(props)) {
+ throw new Error('Array with property names expected as first argument');
+ }
+
+ for (var i = 2; i < arguments.length; i++) {
+ var other = arguments[i];
+
+ for (var p = 0; p < props.length; p++) {
+ var prop = props[p];
+ if (other.hasOwnProperty(prop)) {
+ a[prop] = other[prop];
+ }
+ }
+ }
+ return a;
+ };
+
+ /**
+ * Extend object a with selected properties of object b or a series of objects
+ * Only properties with defined values are copied
+ * @param {Array.<String>} props
+ * @param {Object} a
+ * @param {Object} b
+ * @return {Object} a
+ */
+ exports.selectiveDeepExtend = function (props, a, b) {
+ var allowDeletion = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
+
+ // TODO: add support for Arrays to deepExtend
+ if (Array.isArray(b)) {
+ throw new TypeError('Arrays are not supported by deepExtend');
+ }
+ for (var i = 2; i < arguments.length; i++) {
+ var other = arguments[i];
+ for (var p = 0; p < props.length; p++) {
+ var prop = props[p];
+ if (other.hasOwnProperty(prop)) {
+ if (b[prop] && b[prop].constructor === Object) {
+ if (a[prop] === undefined) {
+ a[prop] = {};
+ }
+ if (a[prop].constructor === Object) {
+ exports.deepExtend(a[prop], b[prop], false, allowDeletion);
+ } else {
+ if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
+ delete a[prop];
+ } else {
+ a[prop] = b[prop];
+ }
+ }
+ } else if (Array.isArray(b[prop])) {
+ throw new TypeError('Arrays are not supported by deepExtend');
+ } else {
+ if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
+ delete a[prop];
+ } else {
+ a[prop] = b[prop];
+ }
+ }
+ }
+ }
+ }
+ return a;
+ };
+
+ /**
+ * Extend object a with selected properties of object b or a series of objects
+ * Only properties with defined values are copied
+ * @param {Array.<String>} props
+ * @param {Object} a
+ * @param {Object} b
+ * @return {Object} a
+ */
+ exports.selectiveNotDeepExtend = function (props, a, b) {
+ var allowDeletion = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
+
+ // TODO: add support for Arrays to deepExtend
+ if (Array.isArray(b)) {
+ throw new TypeError('Arrays are not supported by deepExtend');
+ }
+ for (var prop in b) {
+ if (b.hasOwnProperty(prop)) {
+ if (props.indexOf(prop) == -1) {
+ if (b[prop] && b[prop].constructor === Object) {
+ if (a[prop] === undefined) {
+ a[prop] = {};
+ }
+ if (a[prop].constructor === Object) {
+ exports.deepExtend(a[prop], b[prop]);
+ } else {
+ if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
+ delete a[prop];
+ } else {
+ a[prop] = b[prop];
+ }
+ }
+ } else if (Array.isArray(b[prop])) {
+ a[prop] = [];
+ for (var i = 0; i < b[prop].length; i++) {
+ a[prop].push(b[prop][i]);
+ }
+ } else {
+ if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
+ delete a[prop];
+ } else {
+ a[prop] = b[prop];
+ }
+ }
+ }
+ }
+ }
+ return a;
+ };
+
+ /**
+ * Deep extend an object a with the properties of object b
+ * @param {Object} a
+ * @param {Object} b
+ * @param [Boolean] protoExtend --> optional parameter. If true, the prototype values will also be extended.
+ * (ie. the options objects that inherit from others will also get the inherited options)
+ * @param [Boolean] global --> optional parameter. If true, the values of fields that are null will not deleted
+ * @returns {Object}
+ */
+ exports.deepExtend = function (a, b, protoExtend, allowDeletion) {
+ for (var prop in b) {
+ if (b.hasOwnProperty(prop) || protoExtend === true) {
+ if (b[prop] && b[prop].constructor === Object) {
+ if (a[prop] === undefined) {
+ a[prop] = {};
+ }
+ if (a[prop].constructor === Object) {
+ exports.deepExtend(a[prop], b[prop], protoExtend);
+ } else {
+ if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
+ delete a[prop];
+ } else {
+ a[prop] = b[prop];
+ }
+ }
+ } else if (Array.isArray(b[prop])) {
+ a[prop] = [];
+ for (var i = 0; i < b[prop].length; i++) {
+ a[prop].push(b[prop][i]);
+ }
+ } else {
+ if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
+ delete a[prop];
+ } else {
+ a[prop] = b[prop];
+ }
+ }
+ }
+ }
+ return a;
+ };
+
+ /**
+ * Test whether all elements in two arrays are equal.
+ * @param {Array} a
+ * @param {Array} b
+ * @return {boolean} Returns true if both arrays have the same length and same
+ * elements.
+ */
+ exports.equalArray = function (a, b) {
+ if (a.length != b.length) return false;
+
+ for (var i = 0, len = a.length; i < len; i++) {
+ if (a[i] != b[i]) return false;
+ }
+
+ return true;
+ };
+
+ /**
+ * Convert an object to another type
+ * @param {Boolean | Number | String | Date | Moment | Null | undefined} object
+ * @param {String | undefined} type Name of the type. Available types:
+ * 'Boolean', 'Number', 'String',
+ * 'Date', 'Moment', ISODate', 'ASPDate'.
+ * @return {*} object
+ * @throws Error
+ */
+ exports.convert = function (object, type) {
+ var match;
+
+ if (object === undefined) {
+ return undefined;
+ }
+ if (object === null) {
+ return null;
+ }
+
+ if (!type) {
+ return object;
+ }
+ if (!(typeof type === 'string') && !(type instanceof String)) {
+ throw new Error('Type must be a string');
+ }
+
+ //noinspection FallthroughInSwitchStatementJS
+ switch (type) {
+ case 'boolean':
+ case 'Boolean':
+ return Boolean(object);
+
+ case 'number':
+ case 'Number':
+ return Number(object.valueOf());
+
+ case 'string':
+ case 'String':
+ return String(object);
+
+ case 'Date':
+ if (exports.isNumber(object)) {
+ return new Date(object);
+ }
+ if (object instanceof Date) {
+ return new Date(object.valueOf());
+ } else if (moment.isMoment(object)) {
+ return new Date(object.valueOf());
+ }
+ if (exports.isString(object)) {
+ match = ASPDateRegex.exec(object);
+ if (match) {
+ // object is an ASP date
+ return new Date(Number(match[1])); // parse number
+ } else {
+ return moment(object).toDate(); // parse string
+ }
+ } else {
+ throw new Error('Cannot convert object of type ' + exports.getType(object) + ' to type Date');
+ }
+
+ case 'Moment':
+ if (exports.isNumber(object)) {
+ return moment(object);
+ }
+ if (object instanceof Date) {
+ return moment(object.valueOf());
+ } else if (moment.isMoment(object)) {
+ return moment(object);
+ }
+ if (exports.isString(object)) {
+ match = ASPDateRegex.exec(object);
+ if (match) {
+ // object is an ASP date
+ return moment(Number(match[1])); // parse number
+ } else {
+ return moment(object); // parse string
+ }
+ } else {
+ throw new Error('Cannot convert object of type ' + exports.getType(object) + ' to type Date');
+ }
+
+ case 'ISODate':
+ if (exports.isNumber(object)) {
+ return new Date(object);
+ } else if (object instanceof Date) {
+ return object.toISOString();
+ } else if (moment.isMoment(object)) {
+ return object.toDate().toISOString();
+ } else if (exports.isString(object)) {
+ match = ASPDateRegex.exec(object);
+ if (match) {
+ // object is an ASP date
+ return new Date(Number(match[1])).toISOString(); // parse number
+ } else {
+ return new Date(object).toISOString(); // parse string
+ }
+ } else {
+ throw new Error('Cannot convert object of type ' + exports.getType(object) + ' to type ISODate');
+ }
+
+ case 'ASPDate':
+ if (exports.isNumber(object)) {
+ return '/Date(' + object + ')/';
+ } else if (object instanceof Date) {
+ return '/Date(' + object.valueOf() + ')/';
+ } else if (exports.isString(object)) {
+ match = ASPDateRegex.exec(object);
+ var value;
+ if (match) {
+ // object is an ASP date
+ value = new Date(Number(match[1])).valueOf(); // parse number
+ } else {
+ value = new Date(object).valueOf(); // parse string
+ }
+ return '/Date(' + value + ')/';
+ } else {
+ throw new Error('Cannot convert object of type ' + exports.getType(object) + ' to type ASPDate');
+ }
+
+ default:
+ throw new Error('Unknown type "' + type + '"');
+ }
+ };
+
+ // parse ASP.Net Date pattern,
+ // for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/'
+ // code from http://momentjs.com/
+ var ASPDateRegex = /^\/?Date\((\-?\d+)/i;
+
+ /**
+ * Get the type of an object, for example exports.getType([]) returns 'Array'
+ * @param {*} object
+ * @return {String} type
+ */
+ exports.getType = function (object) {
+ var type = typeof object;
+
+ if (type == 'object') {
+ if (object === null) {
+ return 'null';
+ }
+ if (object instanceof Boolean) {
+ return 'Boolean';
+ }
+ if (object instanceof Number) {
+ return 'Number';
+ }
+ if (object instanceof String) {
+ return 'String';
+ }
+ if (Array.isArray(object)) {
+ return 'Array';
+ }
+ if (object instanceof Date) {
+ return 'Date';
+ }
+ return 'Object';
+ } else if (type == 'number') {
+ return 'Number';
+ } else if (type == 'boolean') {
+ return 'Boolean';
+ } else if (type == 'string') {
+ return 'String';
+ } else if (type === undefined) {
+ return 'undefined';
+ }
+
+ return type;
+ };
+
+ /**
+ * Used to extend an array and copy it. This is used to propagate paths recursively.
+ *
+ * @param arr
+ * @param newValue
+ * @returns {Array}
+ */
+ exports.copyAndExtendArray = function (arr, newValue) {
+ var newArr = [];
+ for (var i = 0; i < arr.length; i++) {
+ newArr.push(arr[i]);
+ }
+ newArr.push(newValue);
+ return newArr;
+ };
+
+ /**
+ * Used to extend an array and copy it. This is used to propagate paths recursively.
+ *
+ * @param arr
+ * @param newValue
+ * @returns {Array}
+ */
+ exports.copyArray = function (arr) {
+ var newArr = [];
+ for (var i = 0; i < arr.length; i++) {
+ newArr.push(arr[i]);
+ }
+ return newArr;
+ };
+
+ /**
+ * Retrieve the absolute left value of a DOM element
+ * @param {Element} elem A dom element, for example a div
+ * @return {number} left The absolute left position of this element
+ * in the browser page.
+ */
+ exports.getAbsoluteLeft = function (elem) {
+ return elem.getBoundingClientRect().left;
+ };
+
+ /**
+ * Retrieve the absolute top value of a DOM element
+ * @param {Element} elem A dom element, for example a div
+ * @return {number} top The absolute top position of this element
+ * in the browser page.
+ */
+ exports.getAbsoluteTop = function (elem) {
+ return elem.getBoundingClientRect().top;
+ };
+
+ /**
+ * add a className to the given elements style
+ * @param {Element} elem
+ * @param {String} className
+ */
+ exports.addClassName = function (elem, className) {
+ var classes = elem.className.split(' ');
+ if (classes.indexOf(className) == -1) {
+ classes.push(className); // add the class to the array
+ elem.className = classes.join(' ');
+ }
+ };
+
+ /**
+ * add a className to the given elements style
+ * @param {Element} elem
+ * @param {String} className
+ */
+ exports.removeClassName = function (elem, className) {
+ var classes = elem.className.split(' ');
+ var index = classes.indexOf(className);
+ if (index != -1) {
+ classes.splice(index, 1); // remove the class from the array
+ elem.className = classes.join(' ');
+ }
+ };
+
+ /**
+ * For each method for both arrays and objects.
+ * In case of an array, the built-in Array.forEach() is applied.
+ * In case of an Object, the method loops over all properties of the object.
+ * @param {Object | Array} object An Object or Array
+ * @param {function} callback Callback method, called for each item in
+ * the object or array with three parameters:
+ * callback(value, index, object)
+ */
+ exports.forEach = function (object, callback) {
+ var i, len;
+ if (Array.isArray(object)) {
+ // array
+ for (i = 0, len = object.length; i < len; i++) {
+ callback(object[i], i, object);
+ }
+ } else {
+ // object
+ for (i in object) {
+ if (object.hasOwnProperty(i)) {
+ callback(object[i], i, object);
+ }
+ }
+ }
+ };
+
+ /**
+ * Convert an object into an array: all objects properties are put into the
+ * array. The resulting array is unordered.
+ * @param {Object} object
+ * @param {Array} array
+ */
+ exports.toArray = function (object) {
+ var array = [];
+
+ for (var prop in object) {
+ if (object.hasOwnProperty(prop)) array.push(object[prop]);
+ }
+
+ return array;
+ };
+
+ /**
+ * Update a property in an object
+ * @param {Object} object
+ * @param {String} key
+ * @param {*} value
+ * @return {Boolean} changed
+ */
+ exports.updateProperty = function (object, key, value) {
+ if (object[key] !== value) {
+ object[key] = value;
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ /**
+ * Throttle the given function to be only executed once every `wait` milliseconds
+ * @param {function} fn
+ * @param {number} wait Time in milliseconds
+ * @returns {function} Returns the throttled function
+ */
+ exports.throttle = function (fn, wait) {
+ var timeout = null;
+ var needExecution = false;
+
+ return function throttled() {
+ if (!timeout) {
+ needExecution = false;
+ fn();
+
+ timeout = setTimeout(function () {
+ timeout = null;
+ if (needExecution) {
+ throttled();
+ }
+ }, wait);
+ } else {
+ needExecution = true;
+ }
+ };
+ };
+
+ /**
+ * Add and event listener. Works for all browsers
+ * @param {Element} element An html element
+ * @param {string} action The action, for example "click",
+ * without the prefix "on"
+ * @param {function} listener The callback function to be executed
+ * @param {boolean} [useCapture]
+ */
+ exports.addEventListener = function (element, action, listener, useCapture) {
+ if (element.addEventListener) {
+ if (useCapture === undefined) useCapture = false;
+
+ if (action === 'mousewheel' && navigator.userAgent.indexOf('Firefox') >= 0) {
+ action = 'DOMMouseScroll'; // For Firefox
+ }
+
+ element.addEventListener(action, listener, useCapture);
+ } else {
+ element.attachEvent('on' + action, listener); // IE browsers
+ }
+ };
+
+ /**
+ * Remove an event listener from an element
+ * @param {Element} element An html dom element
+ * @param {string} action The name of the event, for example "mousedown"
+ * @param {function} listener The listener function
+ * @param {boolean} [useCapture]
+ */
+ exports.removeEventListener = function (element, action, listener, useCapture) {
+ if (element.removeEventListener) {
+ // non-IE browsers
+ if (useCapture === undefined) useCapture = false;
+
+ if (action === 'mousewheel' && navigator.userAgent.indexOf('Firefox') >= 0) {
+ action = 'DOMMouseScroll'; // For Firefox
+ }
+
+ element.removeEventListener(action, listener, useCapture);
+ } else {
+ // IE browsers
+ element.detachEvent('on' + action, listener);
+ }
+ };
+
+ /**
+ * Cancels the event if it is cancelable, without stopping further propagation of the event.
+ */
+ exports.preventDefault = function (event) {
+ if (!event) event = window.event;
+
+ if (event.preventDefault) {
+ event.preventDefault(); // non-IE browsers
+ } else {
+ event.returnValue = false; // IE browsers
+ }
+ };
+
+ /**
+ * Get HTML element which is the target of the event
+ * @param {Event} event
+ * @return {Element} target element
+ */
+ exports.getTarget = function (event) {
+ // code from http://www.quirksmode.org/js/events_properties.html
+ if (!event) {
+ event = window.event;
+ }
+
+ var target;
+
+ if (event.target) {
+ target = event.target;
+ } else if (event.srcElement) {
+ target = event.srcElement;
+ }
+
+ if (target.nodeType != undefined && target.nodeType == 3) {
+ // defeat Safari bug
+ target = target.parentNode;
+ }
+
+ return target;
+ };
+
+ /**
+ * Check if given element contains given parent somewhere in the DOM tree
+ * @param {Element} element
+ * @param {Element} parent
+ */
+ exports.hasParent = function (element, parent) {
+ var e = element;
+
+ while (e) {
+ if (e === parent) {
+ return true;
+ }
+ e = e.parentNode;
+ }
+
+ return false;
+ };
+
+ exports.option = {};
+
+ /**
+ * Convert a value into a boolean
+ * @param {Boolean | function | undefined} value
+ * @param {Boolean} [defaultValue]
+ * @returns {Boolean} bool
+ */
+ exports.option.asBoolean = function (value, defaultValue) {
+ if (typeof value == 'function') {
+ value = value();
+ }
+
+ if (value != null) {
+ return value != false;
+ }
+
+ return defaultValue || null;
+ };
+
+ /**
+ * Convert a value into a number
+ * @param {Boolean | function | undefined} value
+ * @param {Number} [defaultValue]
+ * @returns {Number} number
+ */
+ exports.option.asNumber = function (value, defaultValue) {
+ if (typeof value == 'function') {
+ value = value();
+ }
+
+ if (value != null) {
+ return Number(value) || defaultValue || null;
+ }
+
+ return defaultValue || null;
+ };
+
+ /**
+ * Convert a value into a string
+ * @param {String | function | undefined} value
+ * @param {String} [defaultValue]
+ * @returns {String} str
+ */
+ exports.option.asString = function (value, defaultValue) {
+ if (typeof value == 'function') {
+ value = value();
+ }
+
+ if (value != null) {
+ return String(value);
+ }
+
+ return defaultValue || null;
+ };
+
+ /**
+ * Convert a size or location into a string with pixels or a percentage
+ * @param {String | Number | function | undefined} value
+ * @param {String} [defaultValue]
+ * @returns {String} size
+ */
+ exports.option.asSize = function (value, defaultValue) {
+ if (typeof value == 'function') {
+ value = value();
+ }
+
+ if (exports.isString(value)) {
+ return value;
+ } else if (exports.isNumber(value)) {
+ return value + 'px';
+ } else {
+ return defaultValue || null;
+ }
+ };
+
+ /**
+ * Convert a value into a DOM element
+ * @param {HTMLElement | function | undefined} value
+ * @param {HTMLElement} [defaultValue]
+ * @returns {HTMLElement | null} dom
+ */
+ exports.option.asElement = function (value, defaultValue) {
+ if (typeof value == 'function') {
+ value = value();
+ }
+
+ return value || defaultValue || null;
+ };
+
+ /**
+ * http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
+ *
+ * @param {String} hex
+ * @returns {{r: *, g: *, b: *}} | 255 range
+ */
+ exports.hexToRGB = function (hex) {
+ // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
+ var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+ hex = hex.replace(shorthandRegex, function (m, r, g, b) {
+ return r + r + g + g + b + b;
+ });
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+ return result ? {
+ r: parseInt(result[1], 16),
+ g: parseInt(result[2], 16),
+ b: parseInt(result[3], 16)
+ } : null;
+ };
+
+ /**
+ * This function takes color in hex format or rgb() or rgba() format and overrides the opacity. Returns rgba() string.
+ * @param color
+ * @param opacity
+ * @returns {*}
+ */
+ exports.overrideOpacity = function (color, opacity) {
+ if (color.indexOf('rgba') != -1) {
+ return color;
+ } else if (color.indexOf('rgb') != -1) {
+ var rgb = color.substr(color.indexOf('(') + 1).replace(')', '').split(',');
+ return 'rgba(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ',' + opacity + ')';
+ } else {
+ var rgb = exports.hexToRGB(color);
+ if (rgb == null) {
+ return color;
+ } else {
+ return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + opacity + ')';
+ }
+ }
+ };
+
+ /**
+ *
+ * @param red 0 -- 255
+ * @param green 0 -- 255
+ * @param blue 0 -- 255
+ * @returns {string}
+ * @constructor
+ */
+ exports.RGBToHex = function (red, green, blue) {
+ return '#' + ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1);
+ };
+
+ /**
+ * Parse a color property into an object with border, background, and
+ * highlight colors
+ * @param {Object | String} color
+ * @return {Object} colorObject
+ */
+ exports.parseColor = function (color) {
+ var c;
+ if (exports.isString(color) === true) {
+ if (exports.isValidRGB(color) === true) {
+ var rgb = color.substr(4).substr(0, color.length - 5).split(',').map(function (value) {
+ return parseInt(value);
+ });
+ color = exports.RGBToHex(rgb[0], rgb[1], rgb[2]);
+ }
+ if (exports.isValidHex(color) === true) {
+ var hsv = exports.hexToHSV(color);
+ var lighterColorHSV = { h: hsv.h, s: hsv.s * 0.8, v: Math.min(1, hsv.v * 1.02) };
+ var darkerColorHSV = { h: hsv.h, s: Math.min(1, hsv.s * 1.25), v: hsv.v * 0.8 };
+ var darkerColorHex = exports.HSVToHex(darkerColorHSV.h, darkerColorHSV.s, darkerColorHSV.v);
+ var lighterColorHex = exports.HSVToHex(lighterColorHSV.h, lighterColorHSV.s, lighterColorHSV.v);
+ c = {
+ background: color,
+ border: darkerColorHex,
+ highlight: {
+ background: lighterColorHex,
+ border: darkerColorHex
+ },
+ hover: {
+ background: lighterColorHex,
+ border: darkerColorHex
+ }
+ };
+ } else {
+ c = {
+ background: color,
+ border: color,
+ highlight: {
+ background: color,
+ border: color
+ },
+ hover: {
+ background: color,
+ border: color
+ }
+ };
+ }
+ } else {
+ c = {};
+ c.background = color.background || undefined;
+ c.border = color.border || undefined;
+
+ if (exports.isString(color.highlight)) {
+ c.highlight = {
+ border: color.highlight,
+ background: color.highlight
+ };
+ } else {
+ c.highlight = {};
+ c.highlight.background = color.highlight && color.highlight.background || undefined;
+ c.highlight.border = color.highlight && color.highlight.border || undefined;
+ }
+
+ if (exports.isString(color.hover)) {
+ c.hover = {
+ border: color.hover,
+ background: color.hover
+ };
+ } else {
+ c.hover = {};
+ c.hover.background = color.hover && color.hover.background || undefined;
+ c.hover.border = color.hover && color.hover.border || undefined;
+ }
+ }
+
+ return c;
+ };
+
+ /**
+ * http://www.javascripter.net/faq/rgb2hsv.htm
+ *
+ * @param red
+ * @param green
+ * @param blue
+ * @returns {*}
+ * @constructor
+ */
+ exports.RGBToHSV = function (red, green, blue) {
+ red = red / 255;green = green / 255;blue = blue / 255;
+ var minRGB = Math.min(red, Math.min(green, blue));
+ var maxRGB = Math.max(red, Math.max(green, blue));
+
+ // Black-gray-white
+ if (minRGB == maxRGB) {
+ return { h: 0, s: 0, v: minRGB };
+ }
+
+ // Colors other than black-gray-white:
+ var d = red == minRGB ? green - blue : blue == minRGB ? red - green : blue - red;
+ var h = red == minRGB ? 3 : blue == minRGB ? 1 : 5;
+ var hue = 60 * (h - d / (maxRGB - minRGB)) / 360;
+ var saturation = (maxRGB - minRGB) / maxRGB;
+ var value = maxRGB;
+ return { h: hue, s: saturation, v: value };
+ };
+
+ var cssUtil = {
+ // split a string with css styles into an object with key/values
+ split: function split(cssText) {
+ var styles = {};
+
+ cssText.split(';').forEach(function (style) {
+ if (style.trim() != '') {
+ var parts = style.split(':');
+ var key = parts[0].trim();
+ var value = parts[1].trim();
+ styles[key] = value;
+ }
+ });
+
+ return styles;
+ },
+
+ // build a css text string from an object with key/values
+ join: function join(styles) {
+ return Object.keys(styles).map(function (key) {
+ return key + ': ' + styles[key];
+ }).join('; ');
+ }
+ };
+
+ /**
+ * Append a string with css styles to an element
+ * @param {Element} element
+ * @param {String} cssText
+ */
+ exports.addCssText = function (element, cssText) {
+ var currentStyles = cssUtil.split(element.style.cssText);
+ var newStyles = cssUtil.split(cssText);
+ var styles = exports.extend(currentStyles, newStyles);
+
+ element.style.cssText = cssUtil.join(styles);
+ };
+
+ /**
+ * Remove a string with css styles from an element
+ * @param {Element} element
+ * @param {String} cssText
+ */
+ exports.removeCssText = function (element, cssText) {
+ var styles = cssUtil.split(element.style.cssText);
+ var removeStyles = cssUtil.split(cssText);
+
+ for (var key in removeStyles) {
+ if (removeStyles.hasOwnProperty(key)) {
+ delete styles[key];
+ }
+ }
+
+ element.style.cssText = cssUtil.join(styles);
+ };
+
+ /**
+ * https://gist.github.com/mjijackson/5311256
+ * @param h
+ * @param s
+ * @param v
+ * @returns {{r: number, g: number, b: number}}
+ * @constructor
+ */
+ exports.HSVToRGB = function (h, s, v) {
+ var r, g, b;
+
+ var i = Math.floor(h * 6);
+ var f = h * 6 - i;
+ var p = v * (1 - s);
+ var q = v * (1 - f * s);
+ var t = v * (1 - (1 - f) * s);
+
+ switch (i % 6) {
+ case 0:
+ r = v, g = t, b = p;break;
+ case 1:
+ r = q, g = v, b = p;break;
+ case 2:
+ r = p, g = v, b = t;break;
+ case 3:
+ r = p, g = q, b = v;break;
+ case 4:
+ r = t, g = p, b = v;break;
+ case 5:
+ r = v, g = p, b = q;break;
+ }
+
+ return { r: Math.floor(r * 255), g: Math.floor(g * 255), b: Math.floor(b * 255) };
+ };
+
+ exports.HSVToHex = function (h, s, v) {
+ var rgb = exports.HSVToRGB(h, s, v);
+ return exports.RGBToHex(rgb.r, rgb.g, rgb.b);
+ };
+
+ exports.hexToHSV = function (hex) {
+ var rgb = exports.hexToRGB(hex);
+ return exports.RGBToHSV(rgb.r, rgb.g, rgb.b);
+ };
+
+ exports.isValidHex = function (hex) {
+ var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
+ return isOk;
+ };
+
+ exports.isValidRGB = function (rgb) {
+ rgb = rgb.replace(' ', '');
+ var isOk = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/i.test(rgb);
+ return isOk;
+ };
+ exports.isValidRGBA = function (rgba) {
+ rgba = rgba.replace(' ', '');
+ var isOk = /rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),(.{1,3})\)/i.test(rgba);
+ return isOk;
+ };
+
+ /**
+ * This recursively redirects the prototype of JSON objects to the referenceObject
+ * This is used for default options.
+ *
+ * @param referenceObject
+ * @returns {*}
+ */
+ exports.selectiveBridgeObject = function (fields, referenceObject) {
+ if (typeof referenceObject == 'object') {
+ var objectTo = Object.create(referenceObject);
+ for (var i = 0; i < fields.length; i++) {
+ if (referenceObject.hasOwnProperty(fields[i])) {
+ if (typeof referenceObject[fields[i]] == 'object') {
+ objectTo[fields[i]] = exports.bridgeObject(referenceObject[fields[i]]);
+ }
+ }
+ }
+ return objectTo;
+ } else {
+ return null;
+ }
+ };
+
+ /**
+ * This recursively redirects the prototype of JSON objects to the referenceObject
+ * This is used for default options.
+ *
+ * @param referenceObject
+ * @returns {*}
+ */
+ exports.bridgeObject = function (referenceObject) {
+ if (typeof referenceObject == 'object') {
+ var objectTo = Object.create(referenceObject);
+ for (var i in referenceObject) {
+ if (referenceObject.hasOwnProperty(i)) {
+ if (typeof referenceObject[i] == 'object') {
+ objectTo[i] = exports.bridgeObject(referenceObject[i]);
+ }
+ }
+ }
+ return objectTo;
+ } else {
+ return null;
+ }
+ };
+
+ /**
+ * this is used to set the options of subobjects in the options object. A requirement of these subobjects
+ * is that they have an 'enabled' element which is optional for the user but mandatory for the program.
+ *
+ * @param [object] mergeTarget | this is either this.options or the options used for the groups.
+ * @param [object] options | options
+ * @param [String] option | this is the option key in the options argument
+ * @private
+ */
+ exports.mergeOptions = function (mergeTarget, options, option) {
+ var allowDeletion = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
+ var globalOptions = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];
+
+ if (options[option] === null) {
+ mergeTarget[option] = Object.create(globalOptions[option]);
+ } else {
+ if (options[option] !== undefined) {
+ if (typeof options[option] === 'boolean') {
+ mergeTarget[option].enabled = options[option];
+ } else {
+ if (options[option].enabled === undefined) {
+ mergeTarget[option].enabled = true;
+ }
+ for (var prop in options[option]) {
+ if (options[option].hasOwnProperty(prop)) {
+ mergeTarget[option][prop] = options[option][prop];
+ }
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * This function does a binary search for a visible item in a sorted list. If we find a visible item, the code that uses
+ * this function will then iterate in both directions over this sorted list to find all visible items.
+ *
+ * @param {Item[]} orderedItems | Items ordered by start
+ * @param {function} searchFunction | -1 is lower, 0 is found, 1 is higher
+ * @param {String} field
+ * @param {String} field2
+ * @returns {number}
+ * @private
+ */
+ exports.binarySearchCustom = function (orderedItems, searchFunction, field, field2) {
+ var maxIterations = 10000;
+ var iteration = 0;
+ var low = 0;
+ var high = orderedItems.length - 1;
+
+ while (low <= high && iteration < maxIterations) {
+ var middle = Math.floor((low + high) / 2);
+
+ var item = orderedItems[middle];
+ var value = field2 === undefined ? item[field] : item[field][field2];
+
+ var searchResult = searchFunction(value);
+ if (searchResult == 0) {
+ // jihaa, found a visible item!
+ return middle;
+ } else if (searchResult == -1) {
+ // it is too small --> increase low
+ low = middle + 1;
+ } else {
+ // it is too big --> decrease high
+ high = middle - 1;
+ }
+
+ iteration++;
+ }
+
+ return -1;
+ };
+
+ /**
+ * This function does a binary search for a specific value in a sorted array. If it does not exist but is in between of
+ * two values, we return either the one before or the one after, depending on user input
+ * If it is found, we return the index, else -1.
+ *
+ * @param {Array} orderedItems
+ * @param {{start: number, end: number}} target
+ * @param {String} field
+ * @param {String} sidePreference 'before' or 'after'
+ * @returns {number}
+ * @private
+ */
+ exports.binarySearchValue = function (orderedItems, target, field, sidePreference) {
+ var maxIterations = 10000;
+ var iteration = 0;
+ var low = 0;
+ var high = orderedItems.length - 1;
+ var prevValue, value, nextValue, middle;
+
+ while (low <= high && iteration < maxIterations) {
+ // get a new guess
+ middle = Math.floor(0.5 * (high + low));
+ prevValue = orderedItems[Math.max(0, middle - 1)][field];
+ value = orderedItems[middle][field];
+ nextValue = orderedItems[Math.min(orderedItems.length - 1, middle + 1)][field];
+
+ if (value == target) {
+ // we found the target
+ return middle;
+ } else if (prevValue < target && value > target) {
+ // target is in between of the previous and the current
+ return sidePreference == 'before' ? Math.max(0, middle - 1) : middle;
+ } else if (value < target && nextValue > target) {
+ // target is in between of the current and the next
+ return sidePreference == 'before' ? middle : Math.min(orderedItems.length - 1, middle + 1);
+ } else {
+ // didnt find the target, we need to change our boundaries.
+ if (value < target) {
+ // it is too small --> increase low
+ low = middle + 1;
+ } else {
+ // it is too big --> decrease high
+ high = middle - 1;
+ }
+ }
+ iteration++;
+ }
+
+ // didnt find anything. Return -1.
+ return -1;
+ };
+
+ /*
+ * Easing Functions - inspired from http://gizma.com/easing/
+ * only considering the t value for the range [0, 1] => [0, 1]
+ * https://gist.github.com/gre/1650294
+ */
+ exports.easingFunctions = {
+ // no easing, no acceleration
+ linear: function linear(t) {
+ return t;
+ },
+ // accelerating from zero velocity
+ easeInQuad: function easeInQuad(t) {
+ return t * t;
+ },
+ // decelerating to zero velocity
+ easeOutQuad: function easeOutQuad(t) {
+ return t * (2 - t);
+ },
+ // acceleration until halfway, then deceleration
+ easeInOutQuad: function easeInOutQuad(t) {
+ return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
+ },
+ // accelerating from zero velocity
+ easeInCubic: function easeInCubic(t) {
+ return t * t * t;
+ },
+ // decelerating to zero velocity
+ easeOutCubic: function easeOutCubic(t) {
+ return --t * t * t + 1;
+ },
+ // acceleration until halfway, then deceleration
+ easeInOutCubic: function easeInOutCubic(t) {
+ return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
+ },
+ // accelerating from zero velocity
+ easeInQuart: function easeInQuart(t) {
+ return t * t * t * t;
+ },
+ // decelerating to zero velocity
+ easeOutQuart: function easeOutQuart(t) {
+ return 1 - --t * t * t * t;
+ },
+ // acceleration until halfway, then deceleration
+ easeInOutQuart: function easeInOutQuart(t) {
+ return t < .5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
+ },
+ // accelerating from zero velocity
+ easeInQuint: function easeInQuint(t) {
+ return t * t * t * t * t;
+ },
+ // decelerating to zero velocity
+ easeOutQuint: function easeOutQuint(t) {
+ return 1 + --t * t * t * t * t;
+ },
+ // acceleration until halfway, then deceleration
+ easeInOutQuint: function easeInOutQuint(t) {
+ return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
+ }
+ };
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+ // first check if moment.js is already loaded in the browser window, if so,
+ // use this instance. Else, load via commonjs.
+ 'use strict';
+
+ module.exports = typeof window !== 'undefined' && window['moment'] || __webpack_require__(3);
+
+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function(module) {//! moment.js
+ //! version : 2.10.6
+ //! 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;
+ }
+
+ var momentProperties = utils_hooks__hooks.momentProperties = [];
+
+ function copyConfig(to, from) {
+ var i, prop, val;
+
+ if (typeof from._isAMomentObject !== 'undefined') {
+ to._isAMomentObject = from._isAMomentObject;
+ }
+ if (typeof from._i !== 'undefined') {
+ to._i = from._i;
+ }
+ if (typeof from._f !== 'undefined') {
+ to._f = from._f;
+ }
+ if (typeof from._l !== 'undefined') {
+ to._l = from._l;
+ }
+ if (typeof from._strict !== 'undefined') {
+ to._strict = from._strict;
+ }
+ if (typeof from._tzm !== 'undefined') {
+ to._tzm = from._tzm;
+ }
+ if (typeof from._isUTC !== 'undefined') {
+ to._isUTC = from._isUTC;
+ }
+ if (typeof from._offset !== 'undefined') {
+ to._offset = from._offset;
+ }
+ if (typeof from._pf !== 'undefined') {
+ to._pf = getParsingFlags(from);
+ }
+ if (typeof from._locale !== 'undefined') {
+ to._locale = from._locale;
+ }
+
+ if (momentProperties.length > 0) {
+ for (i in momentProperties) {
+ prop = momentProperties[i];
+ val = from[prop];
+ if (typeof val !== 'undefined') {
+ 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;
+ }
+
+ 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() {
+ }
+
+ 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;
+ !(function webpackMissingModule() { var e = new Error("Cannot find module \"./locale\""); e.code = 'MODULE_NOT_FOUND'; throw e; }());
+ // 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 (typeof values === 'undefined') {
+ 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 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._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
+ }
+
+ function get_set__set (mom, unit, value) {
+ return 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 (typeof this[units] === 'function') {
+ 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 = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|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 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 matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
+
+ // any word (or two) characters or numbers including two/three word month in arabic.
+ 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 isFunction (sth) {
+ // https://github.com/moment/moment/issues/2325
+ return typeof sth === 'function' &&
+ Object.prototype.toString.call(sth) === '[object Function]';
+ }
+
+
+ function addRegexToken (token, regex, strictRegex) {
+ regexes[token] = isFunction(regex) ? regex : function (isStrict) {
+ 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 s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
+ return p1 || p2 || p3 || p4;
+ }).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;
+
+ 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', matchWord);
+ addRegexToken('MMMM', matchWord);
+
+ 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 defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
+ function localeMonths (m) {
+ return this._months[m.month()];
+ }
+
+ var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
+ function localeMonthsShort (m) {
+ return this._monthsShort[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;
+
+ // 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());
+ }
+
+ 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;
+ }
+
+ 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 + '\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;
+
+ var from_string__isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
+
+ var isoDates = [
+ ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
+ ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
+ ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
+ ['GGGG-[W]WW', /\d{4}-W\d{2}/],
+ ['YYYY-DDD', /\d{4}-\d{3}/]
+ ];
+
+ // iso time formats and regexes
+ var isoTimes = [
+ ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
+ ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
+ ['HH:mm', /(T| )\d\d:\d\d/],
+ ['HH', /(T| )\d\d/]
+ ];
+
+ var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
+
+ // date from iso format
+ function configFromISO(config) {
+ var i, l,
+ string = config._i,
+ match = from_string__isoRegex.exec(string);
+
+ if (match) {
+ getParsingFlags(config).iso = true;
+ for (i = 0, l = isoDates.length; i < l; i++) {
+ if (isoDates[i][1].exec(string)) {
+ config._f = isoDates[i][0];
+ break;
+ }
+ }
+ for (i = 0, l = isoTimes.length; i < l; i++) {
+ if (isoTimes[i][1].exec(string)) {
+ // match[6] should be 'T' or space
+ config._f += (match[6] || ' ') + isoTimes[i][0];
+ break;
+ }
+ }
+ if (string.match(matchOffset)) {
+ config._f += 'Z';
+ }
+ 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;
+ utils_hooks__hooks.createFromInputFallback(config);
+ }
+ }
+
+ utils_hooks__hooks.createFromInputFallback = deprecate(
+ 'moment construction falls back to js Date. This is ' +
+ 'discouraged and will be removed in upcoming major ' +
+ 'release. Please refer to ' +
+ 'https://github.com/moment/moment/issues/1407 for more info.',
+ function (config) {
+ config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
+ }
+ );
+
+ 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 doesn't accept years < 1970
+ if (y < 1970) {
+ date.setFullYear(y);
+ }
+ return date;
+ }
+
+ function createUTCDate (y) {
+ var date = new Date(Date.UTC.apply(null, arguments));
+ if (y < 1970) {
+ date.setUTCFullYear(y);
+ }
+ return date;
+ }
+
+ 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');
+
+ // 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 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
+ });
+ addParseToken('YY', function (input, array) {
+ array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
+ });
+
+ // HELPERS
+
+ function daysInYear(year) {
+ return isLeapYear(year) ? 366 : 365;
+ }
+
+ function isLeapYear(year) {
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+ }
+
+ // HOOKS
+
+ utils_hooks__hooks.parseTwoDigitYear = function (input) {
+ return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
+ };
+
+ // MOMENTS
+
+ var getSetYear = makeGetSet('FullYear', false);
+
+ function getIsLeapYear () {
+ return isLeapYear(this.year());
+ }
+
+ addFormatToken('w', ['ww', 2], 'wo', 'week');
+ addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
+
+ // ALIASES
+
+ addUnitAlias('week', 'w');
+ addUnitAlias('isoWeek', 'W');
+
+ // 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
+
+ // firstDayOfWeek 0 = sun, 6 = sat
+ // the day of the week that starts the week
+ // (usually sunday or monday)
+ // firstDayOfWeekOfYear 0 = sun, 6 = sat
+ // the first week is the week that contains the first
+ // of this day of the week
+ // (eg. ISO weeks use thursday (4))
+ function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
+ var end = firstDayOfWeekOfYear - firstDayOfWeek,
+ daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
+ adjustedMoment;
+
+
+ if (daysToDayOfWeek > end) {
+ daysToDayOfWeek -= 7;
+ }
+
+ if (daysToDayOfWeek < end - 7) {
+ daysToDayOfWeek += 7;
+ }
+
+ adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');
+ return {
+ week: Math.ceil(adjustedMoment.dayOfYear() / 7),
+ year: adjustedMoment.year()
+ };
+ }
+
+ // 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');
+ }
+
+ addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
+
+ // ALIASES
+
+ addUnitAlias('dayOfYear', 'DDD');
+
+ // PARSING
+
+ addRegexToken('DDD', match1to3);
+ addRegexToken('DDDD', match3);
+ addParseToken(['DDD', 'DDDD'], function (input, array, config) {
+ config._dayOfYear = toInt(input);
+ });
+
+ // HELPERS
+
+ //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
+ function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
+ var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
+ if (d < firstDayOfWeek) {
+ d += 7;
+ }
+
+ weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
+
+ dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
+
+ return {
+ year: dayOfYear > 0 ? year : year - 1,
+ dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
+ };
+ }
+
+ // 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');
+ }
+
+ // 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) {
+ var now = new Date();
+ if (config._useUTC) {
+ return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];
+ }
+ return [now.getFullYear(), now.getMonth(), now.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;
+
+ 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(local__createLocal(), 1, 4).year);
+ week = defaults(w.W, 1);
+ weekday = defaults(w.E, 1);
+ } else {
+ dow = config._locale._week.dow;
+ doy = config._locale._week.doy;
+
+ weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
+ week = defaults(w.w, 1);
+
+ if (w.d != null) {
+ // weekday -- low day numbers are considered next week
+ weekday = w.d;
+ if (weekday < dow) {
+ ++week;
+ }
+ } else if (w.e != null) {
+ // local weekday -- counting starts from begining of week
+ weekday = w.e + dow;
+ } else {
+ // default to begining of week
+ weekday = dow;
+ }
+ }
+ temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
+
+ config._a[YEAR] = temp.year;
+ config._dayOfYear = temp.dayOfYear;
+ }
+
+ utils_hooks__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 === utils_hooks__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];
+ 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 (getParsingFlags(config).bigHour === true &&
+ config._a[HOUR] <= 12 &&
+
<TRUNCATED>