From de83fe5c7877044842d53d59ab607d6268e16493 Mon Sep 17 00:00:00 2001 From: Ivan Gabriele Date: Mon, 9 Sep 2019 12:31:22 +0200 Subject: [PATCH] 1.6.0 --- dist/_locales/en/messages.json | 1 + dist/background.js | 67 + dist/content.css | 86 + dist/content.js | 5614 ++++++++++++++++++++++++++++++++ dist/icons/icon-128x128.png | Bin 0 -> 77464 bytes dist/icons/icon-16x16.png | Bin 0 -> 7341 bytes dist/icons/icon-32x32-bw.png | Bin 0 -> 8453 bytes dist/icons/icon-32x32.png | Bin 0 -> 11669 bytes dist/icons/icon-48x48.png | Bin 0 -> 18999 bytes dist/icons/icon-501x501.png | Bin 0 -> 1017633 bytes dist/icons/icon-96x96.png | Bin 0 -> 48075 bytes dist/manifest.json | 28 + package.json | 2 +- 13 files changed, 5797 insertions(+), 1 deletion(-) create mode 100644 dist/_locales/en/messages.json create mode 100644 dist/background.js create mode 100644 dist/content.css create mode 100644 dist/content.js create mode 100644 dist/icons/icon-128x128.png create mode 100644 dist/icons/icon-16x16.png create mode 100644 dist/icons/icon-32x32-bw.png create mode 100644 dist/icons/icon-32x32.png create mode 100644 dist/icons/icon-48x48.png create mode 100644 dist/icons/icon-501x501.png create mode 100644 dist/icons/icon-96x96.png create mode 100644 dist/manifest.json diff --git a/dist/_locales/en/messages.json b/dist/_locales/en/messages.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/dist/_locales/en/messages.json @@ -0,0 +1 @@ +{} diff --git a/dist/background.js b/dist/background.js new file mode 100644 index 0000000..d853ede --- /dev/null +++ b/dist/background.js @@ -0,0 +1,67 @@ +(function () { + 'use strict'; + + /* eslint-disable import/prefer-default-export */ + const CHANNEL_MESSAGE = { + CONTENT_IS_MATTERMOST: "TAB_IS_MATTERMOST" + }; + + const ports = []; + chrome.runtime.onConnect.addListener(port => { + if (port.name !== "mattermost-uno") return; + ports[port.sender.tab.id] = port; // eslint-disable-next-line no-shadow + + port.onDisconnect.addListener(port => { + const tabId = port.sender.tab.id; + delete ports[tabId]; + chrome.browserAction.setTitle({ + tabId, + title: "Enable Mattermost Uno" + }); + chrome.browserAction.setIcon({ + tabId, + path: "icons/icon-32x32-bw.png" + }); + }); // eslint-disable-next-line no-shadow + + port.onMessage.addListener((message, port) => { + const tabId = port.sender.tab.id; + + switch (message.value) { + case CHANNEL_MESSAGE.CONTENT_IS_MATTERMOST: + chrome.browserAction.setTitle({ + tabId, + title: "Disable Mattermost Uno" + }); + chrome.browserAction.setIcon({ + tabId, + path: "icons/icon-32x32.png" + }); + break; + + default: + console.error("Something went wrong."); + } + }); + }); + chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { + const { + status + } = changeInfo; + if (status !== "complete") return; + const { + url + } = tab; + if (url === undefined || !url.includes("mattermost")) return; + + if (ports[tabId] === undefined) { + chrome.tabs.insertCSS(tabId, { + file: "content.css" + }); + chrome.tabs.executeScript(tabId, { + file: "content.js" + }); + } + }); + +}()); diff --git a/dist/content.css b/dist/content.css new file mode 100644 index 0000000..a073f8b --- /dev/null +++ b/dist/content.css @@ -0,0 +1,86 @@ +.post-list-holder-by-time .post.post--comment { + display: none; +} + +.MattermostUno-counter { + align-items: baseline; + background-color: rgba(0, 0, 0, 0.05); + border: solid 1px rgba(0, 0, 0, 0.1); + border-radius: 0.5rem; + cursor: pointer; + display: flex; + font-size: 1.2rem; + margin: 0.5rem 0 0.6rem; + max-width: 600px; + padding: 0.4rem 0.75rem 0.35rem; +} +body.MattermostUno--dark .MattermostUno-counter { + background-color: rgba(0, 0, 0, 0.1); + border: solid 1px rgba(255, 255, 255, 0.1); +} +.MattermostUno-counter:hover { + background-color: rgba(0, 0, 0, 0.1); + border: solid 1px rgba(0, 0, 0, 0.25); +} +body.MattermostUno--dark .MattermostUno-counter:hover { + background-color: rgba(0, 0, 0, 0.25); + border: solid 1px rgba(255, 255, 255, 0.5); +} + +.MattermostUno-counterAuthors { + margin-right: 0.25rem; +} +.MattermostUno-counterAuthors > img { + border-radius: 0.25rem; + height: 2rem; + margin-right: 0.5rem; + width: 2rem; +} + +.MattermostUno-counterLink { + color: rgb(17, 83, 171) !important; + font-weight: 700; + margin-left: 0.25rem; +} +body.MattermostUno--dark .MattermostUno-counterLink { + color: #f1f200 !important; +} + +.MattermostUno-counterDescription { + flex-grow: 1; + margin-left: 1rem; + position: relative; +} +.MattermostUno-counterDescriptionOff { + opacity: 0.8; + transition: opacity 0.2s; +} +.MattermostUno-counter:hover .MattermostUno-counterDescriptionOff { + opacity: 0; +} +.MattermostUno-counterDescriptionOn { + bottom: 0; + left: 0; + opacity: 0; + overflow: hidden; + position: absolute; + right: 0; + text-overflow: ellipsis; + top: 0; + transition: opacity 0.2s; + white-space: nowrap; +} +.MattermostUno-counter:hover .MattermostUno-counterDescriptionOn { + opacity: 0.8; +} + +.MattermostUno-counterIcon { + color: transparent; + margin: 0 0 0.45rem; +} +.MattermostUno-counter:hover .MattermostUno-counterIcon { + color: rgb(44, 44, 44); +} +body.MattermostUno--dark .MattermostUno-counter:hover .MattermostUno-counterIcon { + color: rgb(211, 211, 211); +} diff --git a/dist/content.js b/dist/content.js new file mode 100644 index 0000000..da9c9d0 --- /dev/null +++ b/dist/content.js @@ -0,0 +1,5614 @@ +(function () { + 'use strict'; + + function _isPlaceholder(a) { + return a != null && typeof a === 'object' && a['@@functional/placeholder'] === true; + } + + /** + * Optimized internal one-arity curry function. + * + * @private + * @category Function + * @param {Function} fn The function to curry. + * @return {Function} The curried function. + */ + + function _curry1(fn) { + return function f1(a) { + if (arguments.length === 0 || _isPlaceholder(a)) { + return f1; + } else { + return fn.apply(this, arguments); + } + }; + } + + /** + * Optimized internal two-arity curry function. + * + * @private + * @category Function + * @param {Function} fn The function to curry. + * @return {Function} The curried function. + */ + + function _curry2(fn) { + return function f2(a, b) { + switch (arguments.length) { + case 0: + return f2; + + case 1: + return _isPlaceholder(a) ? f2 : _curry1(function (_b) { + return fn(a, _b); + }); + + default: + return _isPlaceholder(a) && _isPlaceholder(b) ? f2 : _isPlaceholder(a) ? _curry1(function (_a) { + return fn(_a, b); + }) : _isPlaceholder(b) ? _curry1(function (_b) { + return fn(a, _b); + }) : fn(a, b); + } + }; + } + + /** + * Optimized internal three-arity curry function. + * + * @private + * @category Function + * @param {Function} fn The function to curry. + * @return {Function} The curried function. + */ + + function _curry3(fn) { + return function f3(a, b, c) { + switch (arguments.length) { + case 0: + return f3; + + case 1: + return _isPlaceholder(a) ? f3 : _curry2(function (_b, _c) { + return fn(a, _b, _c); + }); + + case 2: + return _isPlaceholder(a) && _isPlaceholder(b) ? f3 : _isPlaceholder(a) ? _curry2(function (_a, _c) { + return fn(_a, b, _c); + }) : _isPlaceholder(b) ? _curry2(function (_b, _c) { + return fn(a, _b, _c); + }) : _curry1(function (_c) { + return fn(a, b, _c); + }); + + default: + return _isPlaceholder(a) && _isPlaceholder(b) && _isPlaceholder(c) ? f3 : _isPlaceholder(a) && _isPlaceholder(b) ? _curry2(function (_a, _b) { + return fn(_a, _b, c); + }) : _isPlaceholder(a) && _isPlaceholder(c) ? _curry2(function (_a, _c) { + return fn(_a, b, _c); + }) : _isPlaceholder(b) && _isPlaceholder(c) ? _curry2(function (_b, _c) { + return fn(a, _b, _c); + }) : _isPlaceholder(a) ? _curry1(function (_a) { + return fn(_a, b, c); + }) : _isPlaceholder(b) ? _curry1(function (_b) { + return fn(a, _b, c); + }) : _isPlaceholder(c) ? _curry1(function (_c) { + return fn(a, b, _c); + }) : fn(a, b, c); + } + }; + } + + /** + * Tests whether or not an object is an array. + * + * @private + * @param {*} val The object to test. + * @return {Boolean} `true` if `val` is an array, `false` otherwise. + * @example + * + * _isArray([]); //=> true + * _isArray(null); //=> false + * _isArray({}); //=> false + */ + var _isArray = Array.isArray || function _isArray(val) { + return val != null && val.length >= 0 && Object.prototype.toString.call(val) === '[object Array]'; + }; + + function _isTransformer(obj) { + return obj != null && typeof obj['@@transducer/step'] === 'function'; + } + + /** + * Returns a function that dispatches with different strategies based on the + * object in list position (last argument). If it is an array, executes [fn]. + * Otherwise, if it has a function with one of the given method names, it will + * execute that function (functor case). Otherwise, if it is a transformer, + * uses transducer [xf] to return a new transformer (transducer case). + * Otherwise, it will default to executing [fn]. + * + * @private + * @param {Array} methodNames properties to check for a custom implementation + * @param {Function} xf transducer to initialize if object is transformer + * @param {Function} fn default ramda implementation + * @return {Function} A function that dispatches on object in list position + */ + + function _dispatchable(methodNames, xf, fn) { + return function () { + if (arguments.length === 0) { + return fn(); + } + + var args = Array.prototype.slice.call(arguments, 0); + var obj = args.pop(); + + if (!_isArray(obj)) { + var idx = 0; + + while (idx < methodNames.length) { + if (typeof obj[methodNames[idx]] === 'function') { + return obj[methodNames[idx]].apply(obj, args); + } + + idx += 1; + } + + if (_isTransformer(obj)) { + var transducer = xf.apply(null, args); + return transducer(obj); + } + } + + return fn.apply(this, arguments); + }; + } + + function _reduced(x) { + return x && x['@@transducer/reduced'] ? x : { + '@@transducer/value': x, + '@@transducer/reduced': true + }; + } + + var _xfBase = { + init: function () { + return this.xf['@@transducer/init'](); + }, + result: function (result) { + return this.xf['@@transducer/result'](result); + } + }; + + function _has(prop, obj) { + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + var toString = Object.prototype.toString; + + var _isArguments = + /*#__PURE__*/ + function () { + return toString.call(arguments) === '[object Arguments]' ? function _isArguments(x) { + return toString.call(x) === '[object Arguments]'; + } : function _isArguments(x) { + return _has('callee', x); + }; + }(); + + var hasEnumBug = ! + /*#__PURE__*/ + { + toString: null + }.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['constructor', 'valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; // Safari bug + + var hasArgsEnumBug = + /*#__PURE__*/ + function () { + + return arguments.propertyIsEnumerable('length'); + }(); + + var contains = function contains(list, item) { + var idx = 0; + + while (idx < list.length) { + if (list[idx] === item) { + return true; + } + + idx += 1; + } + + return false; + }; + /** + * Returns a list containing the names of all the enumerable own properties of + * the supplied object. + * Note that the order of the output array is not guaranteed to be consistent + * across different JS platforms. + * + * @func + * @memberOf R + * @since v0.1.0 + * @category Object + * @sig {k: v} -> [k] + * @param {Object} obj The object to extract properties from + * @return {Array} An array of the object's own properties. + * @see R.keysIn, R.values + * @example + * + * R.keys({a: 1, b: 2, c: 3}); //=> ['a', 'b', 'c'] + */ + + + var keys = typeof Object.keys === 'function' && !hasArgsEnumBug ? + /*#__PURE__*/ + _curry1(function keys(obj) { + return Object(obj) !== obj ? [] : Object.keys(obj); + }) : + /*#__PURE__*/ + _curry1(function keys(obj) { + if (Object(obj) !== obj) { + return []; + } + + var prop, nIdx; + var ks = []; + + var checkArgsLength = hasArgsEnumBug && _isArguments(obj); + + for (prop in obj) { + if (_has(prop, obj) && (!checkArgsLength || prop !== 'length')) { + ks[ks.length] = prop; + } + } + + if (hasEnumBug) { + nIdx = nonEnumerableProps.length - 1; + + while (nIdx >= 0) { + prop = nonEnumerableProps[nIdx]; + + if (_has(prop, obj) && !contains(ks, prop)) { + ks[ks.length] = prop; + } + + nIdx -= 1; + } + } + + return ks; + }); + + /** + * Gives a single-word string description of the (native) type of a value, + * returning such answers as 'Object', 'Number', 'Array', or 'Null'. Does not + * attempt to distinguish user Object types any further, reporting them all as + * 'Object'. + * + * @func + * @memberOf R + * @since v0.8.0 + * @category Type + * @sig (* -> {*}) -> String + * @param {*} val The value to test + * @return {String} + * @example + * + * R.type({}); //=> "Object" + * R.type(1); //=> "Number" + * R.type(false); //=> "Boolean" + * R.type('s'); //=> "String" + * R.type(null); //=> "Null" + * R.type([]); //=> "Array" + * R.type(/[A-z]/); //=> "RegExp" + * R.type(() => {}); //=> "Function" + * R.type(undefined); //=> "Undefined" + */ + + var type = + /*#__PURE__*/ + _curry1(function type(val) { + return val === null ? 'Null' : val === undefined ? 'Undefined' : Object.prototype.toString.call(val).slice(8, -1); + }); + + function _arrayFromIterator(iter) { + var list = []; + var next; + + while (!(next = iter.next()).done) { + list.push(next.value); + } + + return list; + } + + function _includesWith(pred, x, list) { + var idx = 0; + var len = list.length; + + while (idx < len) { + if (pred(x, list[idx])) { + return true; + } + + idx += 1; + } + + return false; + } + + function _functionName(f) { + // String(x => x) evaluates to "x => x", so the pattern may not match. + var match = String(f).match(/^function (\w*)/); + return match == null ? '' : match[1]; + } + + // Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + function _objectIs(a, b) { + // SameValue algorithm + if (a === b) { + // Steps 1-5, 7-10 + // Steps 6.b-6.e: +0 != -0 + return a !== 0 || 1 / a === 1 / b; + } else { + // Step 6.a: NaN == NaN + return a !== a && b !== b; + } + } + + var _objectIs$1 = typeof Object.is === 'function' ? Object.is : _objectIs; + + /** + * private _uniqContentEquals function. + * That function is checking equality of 2 iterator contents with 2 assumptions + * - iterators lengths are the same + * - iterators values are unique + * + * false-positive result will be returned for comparision of, e.g. + * - [1,2,3] and [1,2,3,4] + * - [1,1,1] and [1,2,3] + * */ + + function _uniqContentEquals(aIterator, bIterator, stackA, stackB) { + var a = _arrayFromIterator(aIterator); + + var b = _arrayFromIterator(bIterator); + + function eq(_a, _b) { + return _equals(_a, _b, stackA.slice(), stackB.slice()); + } // if *a* array contains any element that is not included in *b* + + + return !_includesWith(function (b, aItem) { + return !_includesWith(eq, aItem, b); + }, b, a); + } + + function _equals(a, b, stackA, stackB) { + if (_objectIs$1(a, b)) { + return true; + } + + var typeA = type(a); + + if (typeA !== type(b)) { + return false; + } + + if (a == null || b == null) { + return false; + } + + if (typeof a['fantasy-land/equals'] === 'function' || typeof b['fantasy-land/equals'] === 'function') { + return typeof a['fantasy-land/equals'] === 'function' && a['fantasy-land/equals'](b) && typeof b['fantasy-land/equals'] === 'function' && b['fantasy-land/equals'](a); + } + + if (typeof a.equals === 'function' || typeof b.equals === 'function') { + return typeof a.equals === 'function' && a.equals(b) && typeof b.equals === 'function' && b.equals(a); + } + + switch (typeA) { + case 'Arguments': + case 'Array': + case 'Object': + if (typeof a.constructor === 'function' && _functionName(a.constructor) === 'Promise') { + return a === b; + } + + break; + + case 'Boolean': + case 'Number': + case 'String': + if (!(typeof a === typeof b && _objectIs$1(a.valueOf(), b.valueOf()))) { + return false; + } + + break; + + case 'Date': + if (!_objectIs$1(a.valueOf(), b.valueOf())) { + return false; + } + + break; + + case 'Error': + return a.name === b.name && a.message === b.message; + + case 'RegExp': + if (!(a.source === b.source && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.sticky === b.sticky && a.unicode === b.unicode)) { + return false; + } + + break; + } + + var idx = stackA.length - 1; + + while (idx >= 0) { + if (stackA[idx] === a) { + return stackB[idx] === b; + } + + idx -= 1; + } + + switch (typeA) { + case 'Map': + if (a.size !== b.size) { + return false; + } + + return _uniqContentEquals(a.entries(), b.entries(), stackA.concat([a]), stackB.concat([b])); + + case 'Set': + if (a.size !== b.size) { + return false; + } + + return _uniqContentEquals(a.values(), b.values(), stackA.concat([a]), stackB.concat([b])); + + case 'Arguments': + case 'Array': + case 'Object': + case 'Boolean': + case 'Number': + case 'String': + case 'Date': + case 'Error': + case 'RegExp': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'ArrayBuffer': + break; + + default: + // Values of other types are only equal if identical. + return false; + } + + var keysA = keys(a); + + if (keysA.length !== keys(b).length) { + return false; + } + + var extendedStackA = stackA.concat([a]); + var extendedStackB = stackB.concat([b]); + idx = keysA.length - 1; + + while (idx >= 0) { + var key = keysA[idx]; + + if (!(_has(key, b) && _equals(b[key], a[key], extendedStackA, extendedStackB))) { + return false; + } + + idx -= 1; + } + + return true; + } + + /** + * Returns `true` if its arguments are equivalent, `false` otherwise. Handles + * cyclical data structures. + * + * Dispatches symmetrically to the `equals` methods of both arguments, if + * present. + * + * @func + * @memberOf R + * @since v0.15.0 + * @category Relation + * @sig a -> b -> Boolean + * @param {*} a + * @param {*} b + * @return {Boolean} + * @example + * + * R.equals(1, 1); //=> true + * R.equals(1, '1'); //=> false + * R.equals([1, 2, 3], [1, 2, 3]); //=> true + * + * const a = {}; a.v = a; + * const b = {}; b.v = b; + * R.equals(a, b); //=> true + */ + + var equals = + /*#__PURE__*/ + _curry2(function equals(a, b) { + return _equals(a, b, [], []); + }); + + var XFindIndex = + /*#__PURE__*/ + function () { + function XFindIndex(f, xf) { + this.xf = xf; + this.f = f; + this.idx = -1; + this.found = false; + } + + XFindIndex.prototype['@@transducer/init'] = _xfBase.init; + + XFindIndex.prototype['@@transducer/result'] = function (result) { + if (!this.found) { + result = this.xf['@@transducer/step'](result, -1); + } + + return this.xf['@@transducer/result'](result); + }; + + XFindIndex.prototype['@@transducer/step'] = function (result, input) { + this.idx += 1; + + if (this.f(input)) { + this.found = true; + result = _reduced(this.xf['@@transducer/step'](result, this.idx)); + } + + return result; + }; + + return XFindIndex; + }(); + + var _xfindIndex = + /*#__PURE__*/ + _curry2(function _xfindIndex(f, xf) { + return new XFindIndex(f, xf); + }); + + /** + * Returns the index of the first element of the list which matches the + * predicate, or `-1` if no element matches. + * + * Acts as a transducer if a transformer is given in list position. + * + * @func + * @memberOf R + * @since v0.1.1 + * @category List + * @sig (a -> Boolean) -> [a] -> Number + * @param {Function} fn The predicate function used to determine if the element is the + * desired one. + * @param {Array} list The array to consider. + * @return {Number} The index of the element found, or `-1`. + * @see R.transduce + * @example + * + * const xs = [{a: 1}, {a: 2}, {a: 3}]; + * R.findIndex(R.propEq('a', 2))(xs); //=> 1 + * R.findIndex(R.propEq('a', 4))(xs); //=> -1 + */ + + var findIndex = + /*#__PURE__*/ + _curry2( + /*#__PURE__*/ + _dispatchable([], _xfindIndex, function findIndex(fn, list) { + var idx = 0; + var len = list.length; + + while (idx < len) { + if (fn(list[idx])) { + return idx; + } + + idx += 1; + } + + return -1; + })); + + /** + * Returns `true` if the specified object property is equal, in + * [`R.equals`](#equals) terms, to the given value; `false` otherwise. + * You can test multiple properties with [`R.whereEq`](#whereEq). + * + * @func + * @memberOf R + * @since v0.1.0 + * @category Relation + * @sig String -> a -> Object -> Boolean + * @param {String} name + * @param {*} val + * @param {*} obj + * @return {Boolean} + * @see R.whereEq, R.propSatisfies, R.equals + * @example + * + * const abby = {name: 'Abby', age: 7, hair: 'blond'}; + * const fred = {name: 'Fred', age: 12, hair: 'brown'}; + * const rusty = {name: 'Rusty', age: 10, hair: 'brown'}; + * const alois = {name: 'Alois', age: 15, disposition: 'surly'}; + * const kids = [abby, fred, rusty, alois]; + * const hasBrownHair = R.propEq('hair', 'brown'); + * R.filter(hasBrownHair, kids); //=> [fred, rusty] + */ + + var propEq = + /*#__PURE__*/ + _curry3(function propEq(name, val, obj) { + return equals(val, obj[name]); + }); + + function e(step, message) { + console.error(`[Mattermost Uno] [${step}] ${message}`); + } + + /* eslint-disable no-bitwise */ + + /** + * @see https://awik.io/determine-color-bright-dark-using-javascript/ + */ + function isColorLight(color) { + // Variables for red, green and blue values: + let r; + let g; + let b; // Check the format of the color, HEX or RGB? + + if (color.match(/^rgb/)) { + // If the color is in HEX, we store the red, green, blue values in separate variables: + const colors = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/); + [, r, g, b] = colors; + } else { + // If the color is in RGB, we convert it to HEX: + // http://gist.github.com/983661 + const colors = +`0x${color.slice(1).replace(color.length < 5 && /./g, "$&$&")}`; + r = colors >> 16; + g = colors >> 8 & 255; + b = colors & 255; + } // HSP (Highly Sensitive Poo) equation: + // http://alienryderflex.com/hsp.html + + + const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b)); // Using the HSP value, we can determine whether the color is light or dark: + + return hsp > 127.5; + } + + function stripHtmlTags(source) { + return source.replace(/(.*)(.*)/g, "$1:$2:$3").replace(/<[^>]*>/g, ""); + } + + function themize(source) { + return source.replace(/[^\s\w-]/g, " ").replace(/\s+/g, " ").trim(); + } + + function waitFor(inMs) { + return new Promise(resolve => setTimeout(resolve, inMs)); + } + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function commonjsRequire () { + throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); + } + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var moment = createCommonjsModule(function (module, exports) { + + (function (global, factory) { + module.exports = factory() ; + })(commonjsGlobal, function () { + + var hookCallback; + + function hooks() { + return hookCallback.apply(null, arguments); + } // This is done to register the method called with moment() + // without creating circular dependencies. + + + function setHookCallback(callback) { + hookCallback = callback; + } + + function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; + } + + function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; + } + + function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return Object.getOwnPropertyNames(obj).length === 0; + } else { + var k; + + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + + return true; + } + } + + function isUndefined(input) { + return input === void 0; + } + + function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; + } + + function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; + } + + function map(arr, fn) { + var res = [], + i; + + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + + return res; + } + + function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); + } + + function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; + } + + function createUTC(input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); + } + + function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty: false, + unusedTokens: [], + unusedInput: [], + overflow: -2, + charsLeftOver: 0, + nullInput: false, + invalidMonth: null, + invalidFormat: false, + userInvalidated: false, + iso: false, + parsedDateParts: [], + meridiem: null, + rfc2822: false, + weekdayMismatch: false + }; + } + + function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + + return m._pf; + } + + var some; + + if (Array.prototype.some) { + some = Array.prototype.some; + } else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; + } + + function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); + var isNowValid = !isNaN(m._d.getTime()) && flags.overflow < 0 && !flags.empty && !flags.invalidMonth && !flags.invalidWeekday && !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || flags.meridiem && parsedParts); + + if (m._strict) { + isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined; + } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } else { + return isNowValid; + } + } + + return m._isValid; + } + + function createInvalid(flags) { + var m = createUTC(NaN); + + if (flags != null) { + extend(getParsingFlags(m), flags); + } else { + getParsingFlags(m).userInvalidated = true; + } + + return m; + } // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + + + var momentProperties = hooks.momentProperties = []; + + function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + + if (!isUndefined(from._i)) { + to._i = from._i; + } + + if (!isUndefined(from._f)) { + to._f = from._f; + } + + if (!isUndefined(from._l)) { + to._l = from._l; + } + + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; + } + + var updateInProgress = false; // Moment prototype object + + function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + + if (!this.isValid()) { + this._d = new Date(NaN); + } // Prevent infinite loop in case updateOffset creates new moment + // objects. + + + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } + } + + function isMoment(obj) { + return obj instanceof Moment || obj != null && obj._isAMomentObject != null; + } + + function absFloor(number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } + } + + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; + } // compare two arrays, return the number of differences + + + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + + for (i = 0; i < len; i++) { + if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) { + diffs++; + } + } + + return diffs + lengthDiff; + } + + function warn(msg) { + if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + + if (firstTime) { + var args = []; + var arg; + + for (var i = 0; i < arguments.length; i++) { + arg = ''; + + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + + args.push(arg); + } + + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack); + firstTime = false; + } + + return fn.apply(this, arguments); + }, fn); + } + + var deprecations = {}; + + function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } + + hooks.suppressDeprecationWarnings = false; + hooks.deprecationHandler = null; + + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } + + function set(config) { + var prop, i; + + for (i in config) { + prop = config[i]; + + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + + this._config = config; // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + + this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source); + } + + function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), + prop; + + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + + for (prop in parentConfig) { + if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + + return res; + } + + function Locale(config) { + if (config != null) { + this.set(config); + } + } + + var keys; + + if (Object.keys) { + keys = Object.keys; + } else { + keys = function (obj) { + var i, + res = []; + + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + + return res; + }; + } + + var defaultCalendar = { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L' + }; + + function calendar(key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; + } + + var defaultLongDateFormat = { + LTS: 'h:mm:ss A', + LT: 'h:mm A', + L: 'MM/DD/YYYY', + LL: 'MMMM D, YYYY', + LLL: 'MMMM D, YYYY h:mm A', + LLLL: 'dddd, MMMM D, YYYY h:mm A' + }; + + function longDateFormat(key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + return this._longDateFormat[key]; + } + + var defaultInvalidDate = 'Invalid date'; + + function invalidDate() { + return this._invalidDate; + } + + var defaultOrdinal = '%d'; + var defaultDayOfMonthOrdinalParse = /\d{1,2}/; + + function ordinal(number) { + return this._ordinal.replace('%d', number); + } + + var defaultRelativeTime = { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years' + }; + + function relativeTime(number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); + } + + function pastFuture(diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); + } + + var aliases = {}; + + function addUnitAlias(unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + } + + function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; + } + + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; + } + + var priorities = {}; + + function addUnitPriority(unit, priority) { + priorities[unit] = priority; + } + + function getPrioritizedUnits(unitsObj) { + var units = []; + + for (var u in unitsObj) { + units.push({ + unit: u, + priority: priorities[u] + }); + } + + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; + } + + function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; + } + + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + var formatFunctions = {}; + var formatTokenFunctions = {}; // token: 'M' + // padded: ['MM', 2] + // ordinal: 'Mo' + // callback: function () { this.month() + 1 } + + function addFormatToken(token, padded, ordinal, callback) { + var func = callback; + + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + + if (token) { + formatTokenFunctions[token] = func; + } + + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } + } + + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + + return input.replace(/\\/g, ''); + } + + function makeFormatFunction(format) { + var array = format.match(formattingTokens), + i, + length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = '', + i; + + for (i = 0; i < length; i++) { + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; + } + + return output; + }; + } // format date using native date object + + + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + return formatFunctions[format](m); + } + + function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; + } + + var match1 = /\d/; // 0 - 9 + + var match2 = /\d\d/; // 00 - 99 + + var match3 = /\d{3}/; // 000 - 999 + + var match4 = /\d{4}/; // 0000 - 9999 + + var match6 = /[+-]?\d{6}/; // -999999 - 999999 + + var match1to2 = /\d\d?/; // 0 - 99 + + var match3to4 = /\d\d\d\d?/; // 999 - 9999 + + var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 + + var match1to3 = /\d{1,3}/; // 0 - 999 + + var match1to4 = /\d{1,4}/; // 0 - 9999 + + var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 + + var matchUnsigned = /\d+/; // 0 - inf + + var matchSigned = /[+-]?\d+/; // -inf - inf + + var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z + + var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + + var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 + // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months + + var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; + var regexes = {}; + + function addRegexToken(token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return isStrict && strictRegex ? strictRegex : regex; + }; + } + + function getParseRegexForToken(token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); + } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + + + function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); + } + + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + var tokens = {}; + + function addParseToken(token, callback) { + var i, + func = callback; + + if (typeof token === 'string') { + token = [token]; + } + + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } + } + + function addWeekParseToken(token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); + } + + function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } + } + + var YEAR = 0; + var MONTH = 1; + var DATE = 2; + var HOUR = 3; + var MINUTE = 4; + var SECOND = 5; + var MILLISECOND = 6; + var WEEK = 7; + var WEEKDAY = 8; // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES + + addUnitAlias('year', 'y'); // PRIORITIES + + addUnitPriority('year', 1); // PARSING + + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); // HELPERS + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + function isLeapYear(year) { + return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; + } // HOOKS + + + hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; // MOMENTS + + + var getSetYear = makeGetSet('FullYear', true); + + function getIsLeapYear() { + return isLeapYear(this.year()); + } + + function makeGetSet(unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; + } + + function get(mom, unit) { + return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; + } + + function set$1(mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + } // MOMENTS + + + function stringGet(units) { + units = normalizeUnits(units); + + if (isFunction(this[units])) { + return this[units](); + } + + return this; + } + + function stringSet(units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + + if (isFunction(this[units])) { + return this[units](value); + } + } + + return this; + } + + function mod(n, x) { + return (n % x + x) % x; + } + + var indexOf; + + if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; + } else { + indexOf = function (o) { + // I know + var i; + + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + + return -1; + }; + } + + function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2; + } // FORMATTING + + + addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; + }); + addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); + }); + addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); + }); // ALIASES + + addUnitAlias('month', 'M'); // PRIORITY + + addUnitPriority('month', 8); // PARSING + + addRegexToken('M', match1to2); + addRegexToken('MM', match1to2, match2); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); + addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; + }); + addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid. + + + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } + }); // LOCALES + + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; + var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); + + function localeMonths(m, format) { + if (!m) { + return isArray(this._months) ? this._months : this._months['standalone']; + } + + return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; + } + + var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); + + function localeMonthsShort(m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone']; + } + + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + function handleStrictParse(monthName, format, strict) { + var i, + ii, + mom, + llc = monthName.toLocaleLowerCase(); + + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeMonthsParse(monthName, format, strict) { + var i, mom, regex; + + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + + + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } // test the regex + + + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } + } // MOMENTS + + + function setMonth(mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); // TODO: Another silent failure? + + if (!isNumber(value)) { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + + return mom; + } + + function getSetMonth(value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } + } + + function getDaysInMonth() { + return daysInMonth(this.year(), this.month()); + } + + var defaultMonthsShortRegex = matchWord; + + function monthsShortRegex(isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + + return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex; + } + } + + var defaultMonthsRegex = matchWord; + + function monthsRegex(isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + + return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex; + } + } + + function computeMonthsParse() { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], + longPieces = [], + mixedPieces = [], + i, + mom; + + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + + + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + } + + function createDate(y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date; // the date constructor remaps years 0-99 to 1900-1999 + + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + date = new Date(y + 400, m, d, h, M, s, ms); + + if (isFinite(date.getFullYear())) { + date.setFullYear(y); + } + } else { + date = new Date(y, m, d, h, M, s, ms); + } + + return date; + } + + function createUTCDate(y) { + var date; // the Date.UTC function remaps years 0-99 to 1900-1999 + + if (y < 100 && y >= 0) { + var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset + + args[0] = y + 400; + date = new Date(Date.UTC.apply(null, args)); + + if (isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + } else { + date = new Date(Date.UTC.apply(null, arguments)); + } + + return date; + } // start-of-first-week - start-of-year + + + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + return -fwdlw + fwd - 1; + } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + + + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, + resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; + } + + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, + resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; + } + + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; + } // FORMATTING + + + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES + + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); // PRIORITIES + + addUnitPriority('week', 5); + addUnitPriority('isoWeek', 5); // PARSING + + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); + addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + }); // HELPERS + // LOCALES + + function localeWeek(mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } + + var defaultLocaleWeek = { + dow: 0, + // Sunday is the first day of the week. + doy: 6 // The week that contains Jan 6th is the first week of the year. + + }; + + function localeFirstDayOfWeek() { + return this._week.dow; + } + + function localeFirstDayOfYear() { + return this._week.doy; + } // MOMENTS + + + function getSetWeek(input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + function getSetISOWeek(input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } // FORMATTING + + + addFormatToken('d', 0, 'do', 'day'); + addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); + }); + addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); + }); + addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); + }); + addFormatToken('e', 0, 0, 'weekday'); + addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES + + addUnitAlias('day', 'd'); + addUnitAlias('weekday', 'e'); + addUnitAlias('isoWeekday', 'E'); // PRIORITY + + addUnitPriority('day', 11); + addUnitPriority('weekday', 11); + addUnitPriority('isoWeekday', 11); // PARSING + + addRegexToken('d', match1to2); + addRegexToken('e', match1to2); + addRegexToken('E', match1to2); + addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); + }); + addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); + }); + addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); + }); + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid + + + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } + }); + addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); + }); // HELPERS + + function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + + if (typeof input === 'number') { + return input; + } + + return null; + } + + function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + + return isNaN(input) ? null : input; + } // LOCALES + + + function shiftWeekdays(ws, n) { + return ws.slice(n, 7).concat(ws.slice(0, n)); + } + + var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); + + function localeWeekdays(m, format) { + var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone']; + return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays; + } + + var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); + + function localeWeekdaysShort(m) { + return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort; + } + + var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); + + function localeWeekdaysMin(m) { + return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin; + } + + function handleStrictParse$1(weekdayName, format, strict) { + var i, + ii, + mom, + llc = weekdayName.toLocaleLowerCase(); + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._shortWeekdaysParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._weekdaysParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._weekdaysParse, llc); + + if (ii !== -1) { + return ii; + } + + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeWeekdaysParse(weekdayName, format, strict) { + var i, mom, regex; + + if (this._weekdaysParseExact) { + return handleStrictParse$1.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); + } + + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } // test the regex + + + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + } // MOMENTS + + + function getSetDayOfWeek(input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + } + + function getSetLocaleDayOfWeek(input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + } + + function getSetISODayOfWeek(input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + + + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } + } + + var defaultWeekdaysRegex = matchWord; + + function weekdaysRegex(isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + + return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex; + } + } + + var defaultWeekdaysShortRegex = matchWord; + + function weekdaysShortRegex(isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + + return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } + } + + var defaultWeekdaysMinRegex = matchWord; + + function weekdaysMinRegex(isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + + return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } + } + + function computeWeekdaysParse() { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], + shortPieces = [], + longPieces = [], + mixedPieces = [], + i, + mom, + minp, + shortp, + longp; + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + + + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); + } // FORMATTING + + + function hFormat() { + return this.hours() % 12 || 12; + } + + function kFormat() { + return this.hours() || 24; + } + + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + addFormatToken('k', ['kk', 2], 0, kFormat); + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); + addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2); + }); + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2); + }); + + function meridiem(token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); + } + + meridiem('a', true); + meridiem('A', false); // ALIASES + + addUnitAlias('hour', 'h'); // PRIORITY + + addUnitPriority('hour', 13); // PARSING + + function matchMeridiem(isStrict, locale) { + return locale._meridiemParse; + } + + addRegexToken('a', matchMeridiem); + addRegexToken('A', matchMeridiem); + addRegexToken('H', match1to2); + addRegexToken('h', match1to2); + addRegexToken('k', match1to2); + addRegexToken('HH', match1to2, match2); + addRegexToken('hh', match1to2, match2); + addRegexToken('kk', match1to2, match2); + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); + addParseToken(['H', 'HH'], HOUR); + addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; + }); + addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; + }); + addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); // LOCALES + + function localeIsPM(input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return (input + '').toLowerCase().charAt(0) === 'p'; + } + + var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; + + function localeMeridiem(hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + } // MOMENTS + // Setting the hour should keep the time, because the user explicitly + // specified which hour they want. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + + + var getSetHour = makeGetSet('Hours', true); + var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, + week: defaultLocaleWeek, + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, + meridiemParse: defaultLocaleMeridiemParse + }; // internal storage for locale config files + + var locales = {}; + var localeFamilies = {}; + var globalLocale; + + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; + } // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + + + function chooseLocale(names) { + var i = 0, + j, + next, + locale, + split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + + if (locale) { + return locale; + } + + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + + j--; + } + + i++; + } + + return globalLocale; + } + + function loadLocale(name) { + var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node + + if (!locales[name] && 'object' !== 'undefined' && module && module.exports) { + try { + oldLocale = globalLocale._abbr; + var aliasedRequire = commonjsRequire; + aliasedRequire('./locale/' + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} + } + + return locales[name]; + } // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + + + function getSetGlobalLocale(key, values) { + var data; + + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } else { + if (typeof console !== 'undefined' && console.warn) { + //warn user if arguments are passed but the locale could not be set + console.warn('Locale ' + key + ' not found. Did you forget to load it?'); + } + } + } + + return globalLocale._abbr; + } + + function defineLocale(name, config) { + if (config !== null) { + var locale, + parentConfig = baseConfig; + config.abbr = name; + + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', 'use moment.updateLocale(localeName, config) to change ' + 'an existing locale. moment.defineLocale(localeName, ' + 'config) should only be used for creating a new locale ' + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + locale = loadLocale(config.parentLocale); + + if (locale != null) { + parentConfig = locale._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } + } + } + + locales[name] = new Locale(mergeConfigs(parentConfig, config)); + + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + + + getSetGlobalLocale(name); + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + } + + function updateLocale(name, config) { + if (config != null) { + var locale, + tmpLocale, + parentConfig = baseConfig; // MERGE + + tmpLocale = loadLocale(name); + + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + + config = mergeConfigs(parentConfig, config); + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; // backwards compat for now: also set the locale + + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + + return locales[name]; + } // returns locale data + + + function getLocale(key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + + if (locale) { + return locale; + } + + key = [key]; + } + + return chooseLocale(key); + } + + function listLocales() { + return keys(locales); + } + + function checkOverflow(m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : a[HOUR] < 0 || a[HOUR] > 24 || a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0) ? HOUR : a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; + } // Pick the first defined of two or three arguments. + + + function defaults(a, b, c) { + if (a != null) { + return a; + } + + if (b != null) { + return b; + } + + return c; + } + + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + } // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + + + function configFromArray(config) { + var i, + date, + input = [], + currentDate, + expectedWeekday, + yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays + + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } //if the day of the year is set, figure out what it is + + + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + + + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } // Zero out whatever was not defaulted, including time + + + for (; i < 7; i++) { + config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i]; + } // Check for 24:00:00.000 + + + if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } // check for mismatching day of week + + + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { + getParsingFlags(config).weekdayMismatch = true; + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + w = config._w; + + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + var curWeek = weekOfYear(createLocal(), dow, doy); + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week. + + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from beginning of week + weekday = w.e + dow; + + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to beginning of week + weekday = dow; + } + } + + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + } // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + + + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + var isoDates = [['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], ['GGGG-[W]WW', /\d{4}-W\d\d/, false], ['YYYY-DDD', /\d{4}-\d{3}/], ['YYYY-MM', /\d{4}-\d\d/, false], ['YYYYYYMMDD', /[+-]\d{10}/], ['YYYYMMDD', /\d{8}/], // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], ['GGGG[W]WW', /\d{4}W\d{2}/, false], ['YYYYDDD', /\d{7}/]]; // iso time formats and regexes + + var isoTimes = [['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], ['HH:mm:ss', /\d\d:\d\d:\d\d/], ['HH:mm', /\d\d:\d\d/], ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], ['HHmmss', /\d\d\d\d\d\d/], ['HHmm', /\d\d\d\d/], ['HH', /\d\d/]]; + var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format + + function configFromISO(config) { + var i, + l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, + dateFormat, + timeFormat, + tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + + if (dateFormat == null) { + config._isValid = false; + return; + } + + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + + if (timeFormat == null) { + config._isValid = false; + return; + } + } + + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } + } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 + + + var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; + + function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; + } + + function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + + return year; + } + + function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + + function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + + return true; + } + + var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 + }; + + function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, + h = (hm - m) / 100; + return h * 60 + m; + } + } // date and time from ref 2822 format + + + function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + config._d = createUTCDate.apply(null, config._a); + + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } + } // date from iso format or fallback + + + function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + configFromRFC2822(config); + + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } // Final attempt, use Input Fallback + + + hooks.createFromInputFallback(config); + } + + hooks.createFromInputFallback = deprecate('value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 'discouraged and will be removed in an upcoming major release. Please refer to ' + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + }); // constant that refers to the ISO standard + + hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form + + + hooks.RFC_2822 = function () {}; // date from string and format string + + + function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + + config._a = []; + getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC` + + var string = '' + config._i, + i, + parsedInput, + tokens, + token, + skipped, + stringLength = string.length, + totalParsedInputLength = 0; + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } // don't parse if it's not a known token + + + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } else { + getParsingFlags(config).unusedTokens.push(token); + } + + addTimeToArrayFromToken(token, parsedInput, config); + } else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } // add remaining unparsed input length to the string + + + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } // clear _12h flag if hour is <= 12 + + + if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; + } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; // handle meridiem + + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + configFromArray(config); + checkOverflow(config); + } + + function meridiemFixWrap(locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + + if (isPm && hour < 12) { + hour += 12; + } + + if (!isPm && hour === 12) { + hour = 0; + } + + return hour; + } else { + // this is not supposed to happen + return hour; + } + } // date from string and array of format strings + + + function configFromStringAndArray(config) { + var tempConfig, bestMoment, scoreToBeat, i, currentScore; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (!isValid(tempConfig)) { + continue; + } // if there is any input that was not parsed add a penalty for that format + + + currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens + + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); + } + + function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + configFromArray(config); + } + + function createFromConfig(config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; + } + + function prepareConfig(config) { + var input = config._i, + format = config._f; + config._locale = config._locale || getLocale(config._l); + + if (input === null || format === undefined && input === '') { + return createInvalid({ + nullInput: true + }); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } + + if (!isValid(config)) { + config._d = null; + } + + return config; + } + + function configFromInput(config) { + var input = config._i; + + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } + } + + function createLocalOrUTC(input, format, locale, strict, isUTC) { + var c = {}; + + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } + + if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) { + input = undefined; + } // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + + + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + return createFromConfig(c); + } + + function createLocal(input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); + } + + var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () { + var other = createLocal.apply(null, arguments); + + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + }); + var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () { + var other = createLocal.apply(null, arguments); + + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + }); // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + + function pickBy(fn, moments) { + var res, i; + + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + + if (!moments.length) { + return createLocal(); + } + + res = moments[0]; + + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + + return res; + } // TODO: Use [].sort instead? + + + function min() { + var args = [].slice.call(arguments, 0); + return pickBy('isBefore', args); + } + + function max() { + var args = [].slice.call(arguments, 0); + return pickBy('isAfter', args); + } + + var now = function () { + return Date.now ? Date.now() : +new Date(); + }; + + var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + + function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } + } + + var unitHasDecimal = false; + + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; + } + + function isValid$1() { + return this._isValid; + } + + function createInvalid$1() { + return createDuration(NaN); + } + + function Duration(duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || normalizedInput.isoWeek || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove + + this._milliseconds = +milliseconds + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + + this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + + this._months = +months + quarters * 3 + years * 12; + this._data = {}; + this._locale = getLocale(); + + this._bubble(); + } + + function isDuration(obj) { + return obj instanceof Duration; + } + + function absRound(number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } // FORMATTING + + + function offset(token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + + if (offset < 0) { + offset = -offset; + sign = '-'; + } + + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2); + }); + } + + offset('Z', ':'); + offset('ZZ', ''); // PARSING + + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); + addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); + }); // HELPERS + // timezone chunker + // '+10:00' > ['10', '00'] + // '-1530' > ['-15', '30'] + + var chunkOffset = /([\+\-]|\d\d)/gi; + + function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher); + + if (matches === null) { + return null; + } + + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes; + } // Return a moment from input, that is local/utc/zone equivalent to model. + + + function cloneWithOffset(input, model) { + var res, diff; + + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api. + + res._d.setTime(res._d.valueOf() + diff); + + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } + } + + function getDateOffset(m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; + } // HOOKS + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + + + hooks.updateOffset = function () {}; // MOMENTS + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + + + function getSetOffset(input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + + if (!this.isValid()) { + return input != null ? this : NaN; + } + + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + + this._offset = input; + this._isUTC = true; + + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract(this, createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } + } + + function getSetZone(input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + return this; + } else { + return -this.utcOffset(); + } + } + + function setOffsetToUTC(keepLocalTime) { + return this.utcOffset(0, keepLocalTime); + } + + function setOffsetToLocal(keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + + return this; + } + + function setOffsetToParsedOffset() { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + + if (tZone != null) { + this.utcOffset(tZone); + } else { + this.utcOffset(0, true); + } + } + + return this; + } + + function hasAlignedHourOffset(input) { + if (!this.isValid()) { + return false; + } + + input = input ? createLocal(input).utcOffset() : 0; + return (this.utcOffset() - input) % 60 === 0; + } + + function isDaylightSavingTime() { + return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset(); + } + + function isDaylightSavingTimeShifted() { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; + } + + function isLocal() { + return this.isValid() ? !this._isUTC : false; + } + + function isUtcOffset() { + return this.isValid() ? this._isUTC : false; + } + + function isUtc() { + return this.isValid() ? this._isUTC && this._offset === 0 : false; + } // ASP.NET json date format regex + + + var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + // and further modified to allow for strings containing both week and day + + var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + + function createDuration(input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms: input._milliseconds, + d: input._days, + M: input._months + }; + } else if (isNumber(input)) { + duration = {}; + + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = match[1] === '-' ? -1 : 1; + duration = { + y: 0, + d: toInt(match[DATE]) * sign, + h: toInt(match[HOUR]) * sign, + m: toInt(match[MINUTE]) * sign, + s: toInt(match[SECOND]) * sign, + ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match + + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = match[1] === '-' ? -1 : 1; + duration = { + y: parseIso(match[2], sign), + M: parseIso(match[3], sign), + w: parseIso(match[4], sign), + d: parseIso(match[5], sign), + h: parseIso(match[6], sign), + m: parseIso(match[7], sign), + s: parseIso(match[8], sign) + }; + } else if (duration == null) { + // checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + return ret; + } + + createDuration.fn = Duration.prototype; + createDuration.invalid = createInvalid$1; + + function parseIso(inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it + + return (isNaN(res) ? 0 : res) * sign; + } + + function positiveMomentsDifference(base, other) { + var res = {}; + res.months = other.month() - base.month() + (other.year() - base.year()) * 12; + + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +base.clone().add(res.months, 'M'); + return res; + } + + function momentsDifference(base, other) { + var res; + + if (!(base.isValid() && other.isValid())) { + return { + milliseconds: 0, + months: 0 + }; + } + + other = cloneWithOffset(other, base); + + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } // TODO: remove 'name' arg after deprecation is removed + + + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; //invert the arguments, but complain about it + + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); + tmp = val; + val = period; + period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; + } + + function addSubtract(mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } + } + + var add = createAdder(1, 'add'); + var subtract = createAdder(-1, 'subtract'); + + function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; + } + + function calendar$1(time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; + var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); + } + + function clone() { + return new Moment(this); + } + + function isAfter(input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + + if (!(this.isValid() && localInput.isValid())) { + return false; + } + + units = normalizeUnits(units) || 'millisecond'; + + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } + } + + function isBefore(input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + + if (!(this.isValid() && localInput.isValid())) { + return false; + } + + units = normalizeUnits(units) || 'millisecond'; + + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } + } + + function isBetween(from, to, units, inclusivity) { + var localFrom = isMoment(from) ? from : createLocal(from), + localTo = isMoment(to) ? to : createLocal(to); + + if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { + return false; + } + + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); + } + + function isSame(input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + + if (!(this.isValid() && localInput.isValid())) { + return false; + } + + units = normalizeUnits(units) || 'millisecond'; + + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + } + } + + function isSameOrAfter(input, units) { + return this.isSame(input, units) || this.isAfter(input, units); + } + + function isSameOrBefore(input, units) { + return this.isSame(input, units) || this.isBefore(input, units); + } + + function diff(input, units, asFloat) { + var that, zoneDelta, output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + units = normalizeUnits(units); + + switch (units) { + case 'year': + output = monthDiff(this, that) / 12; + break; + + case 'month': + output = monthDiff(this, that); + break; + + case 'quarter': + output = monthDiff(this, that) / 3; + break; + + case 'second': + output = (this - that) / 1e3; + break; + // 1000 + + case 'minute': + output = (this - that) / 6e4; + break; + // 1000 * 60 + + case 'hour': + output = (this - that) / 36e5; + break; + // 1000 * 60 * 60 + + case 'day': + output = (this - that - zoneDelta) / 864e5; + break; + // 1000 * 60 * 60 * 24, negate dst + + case 'week': + output = (this - that - zoneDelta) / 6048e5; + break; + // 1000 * 60 * 60 * 24 * 7, negate dst + + default: + output = this - that; + } + + return asFloat ? output : absFloor(output); + } + + function monthDiff(a, b) { + // difference in months + var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, + adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month + + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month + + adjust = (b - anchor) / (anchor2 - anchor); + } //check for negative zero, return zero if negative zero + + + return -(wholeMonthDiff + adjust) || 0; + } + + hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + + function toString() { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + } + + function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + + var utc = keepOffset !== true; + var m = utc ? this.clone().utc() : this; + + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { + return this.toDate().toISOString(); + } else { + return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); + } + } + + return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + /** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ + + + function inspect() { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + + var func = 'moment'; + var zone = ''; + + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + + var prefix = '[' + func + '("]'; + var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; + return this.format(prefix + year + datetime + suffix); + } + + function format(inputString) { + if (!inputString) { + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; + } + + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); + } + + function from(time, withoutSuffix) { + if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) { + return createDuration({ + to: this, + from: time + }).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function fromNow(withoutSuffix) { + return this.from(createLocal(), withoutSuffix); + } + + function to(time, withoutSuffix) { + if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) { + return createDuration({ + from: this, + to: time + }).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function toNow(withoutSuffix) { + return this.to(createLocal(), withoutSuffix); + } // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + + + function locale(key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + + if (newLocaleData != null) { + this._locale = newLocaleData; + } + + return this; + } + } + + var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + }); + + function localeData() { + return this._locale; + } + + var MS_PER_SECOND = 1000; + var MS_PER_MINUTE = 60 * MS_PER_SECOND; + var MS_PER_HOUR = 60 * MS_PER_MINUTE; + var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970): + + function mod$1(dividend, divisor) { + return (dividend % divisor + divisor) % divisor; + } + + function localStartOfDate(y, m, d) { + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return new Date(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return new Date(y, m, d).valueOf(); + } + } + + function utcStartOfDate(y, m, d) { + // Date.UTC remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return Date.UTC(y, m, d); + } + } + + function startOf(units) { + var time; + units = normalizeUnits(units); + + if (units === undefined || units === 'millisecond' || !this.isValid()) { + return this; + } + + var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + + switch (units) { + case 'year': + time = startOfDate(this.year(), 0, 1); + break; + + case 'quarter': + time = startOfDate(this.year(), this.month() - this.month() % 3, 1); + break; + + case 'month': + time = startOfDate(this.year(), this.month(), 1); + break; + + case 'week': + time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); + break; + + case 'isoWeek': + time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); + break; + + case 'day': + case 'date': + time = startOfDate(this.year(), this.month(), this.date()); + break; + + case 'hour': + time = this._d.valueOf(); + time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); + break; + + case 'minute': + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_MINUTE); + break; + + case 'second': + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_SECOND); + break; + } + + this._d.setTime(time); + + hooks.updateOffset(this, true); + return this; + } + + function endOf(units) { + var time; + units = normalizeUnits(units); + + if (units === undefined || units === 'millisecond' || !this.isValid()) { + return this; + } + + var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + + switch (units) { + case 'year': + time = startOfDate(this.year() + 1, 0, 1) - 1; + break; + + case 'quarter': + time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; + break; + + case 'month': + time = startOfDate(this.year(), this.month() + 1, 1) - 1; + break; + + case 'week': + time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; + break; + + case 'isoWeek': + time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; + break; + + case 'day': + case 'date': + time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; + break; + + case 'hour': + time = this._d.valueOf(); + time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; + break; + + case 'minute': + time = this._d.valueOf(); + time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; + break; + + case 'second': + time = this._d.valueOf(); + time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; + break; + } + + this._d.setTime(time); + + hooks.updateOffset(this, true); + return this; + } + + function valueOf() { + return this._d.valueOf() - (this._offset || 0) * 60000; + } + + function unix() { + return Math.floor(this.valueOf() / 1000); + } + + function toDate() { + return new Date(this.valueOf()); + } + + function toArray() { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; + } + + function toObject() { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; + } + + function toJSON() { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; + } + + function isValid$2() { + return isValid(this); + } + + function parsingFlags() { + return extend({}, getParsingFlags(this)); + } + + function invalidAt() { + return getParsingFlags(this).overflow; + } + + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; + } // FORMATTING + + + addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; + }); + addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; + }); + + function addWeekYearFormatToken(token, getter) { + addFormatToken(0, [token, token.length], 0, getter); + } + + addWeekYearFormatToken('gggg', 'weekYear'); + addWeekYearFormatToken('ggggg', 'weekYear'); + addWeekYearFormatToken('GGGG', 'isoWeekYear'); + addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES + + addUnitAlias('weekYear', 'gg'); + addUnitAlias('isoWeekYear', 'GG'); // PRIORITY + + addUnitPriority('weekYear', 1); + addUnitPriority('isoWeekYear', 1); // PARSING + + addRegexToken('G', matchSigned); + addRegexToken('g', matchSigned); + addRegexToken('GG', match1to2, match2); + addRegexToken('gg', match1to2, match2); + addRegexToken('GGGG', match1to4, match4); + addRegexToken('gggg', match1to4, match4); + addRegexToken('GGGGG', match1to6, match6); + addRegexToken('ggggg', match1to6, match6); + addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); + }); + addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); + }); // MOMENTS + + function getSetWeekYear(input) { + return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy); + } + + function getSetISOWeekYear(input) { + return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4); + } + + function getISOWeeksInYear() { + return weeksInYear(this.year(), 1, 4); + } + + function getWeeksInYear() { + var weekInfo = this.localeData()._week; + + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + } + + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + + if (week > weeksTarget) { + week = weeksTarget; + } + + return setWeekAll.call(this, input, week, weekday, dow, doy); + } + } + + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; + } // FORMATTING + + + addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES + + addUnitAlias('quarter', 'Q'); // PRIORITY + + addUnitPriority('quarter', 7); // PARSING + + addRegexToken('Q', match1); + addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; + }); // MOMENTS + + function getSetQuarter(input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + } // FORMATTING + + + addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES + + addUnitAlias('date', 'D'); // PRIORITY + + addUnitPriority('date', 9); // PARSING + + addRegexToken('D', match1to2); + addRegexToken('DD', match1to2, match2); + addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient; + }); + addParseToken(['D', 'DD'], DATE); + addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0]); + }); // MOMENTS + + var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING + + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES + + addUnitAlias('dayOfYear', 'DDD'); // PRIORITY + + addUnitPriority('dayOfYear', 4); // PARSING + + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); // HELPERS + // MOMENTS + + function getSetDayOfYear(input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add(input - dayOfYear, 'd'); + } // FORMATTING + + + addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES + + addUnitAlias('minute', 'm'); // PRIORITY + + addUnitPriority('minute', 14); // PARSING + + addRegexToken('m', match1to2); + addRegexToken('mm', match1to2, match2); + addParseToken(['m', 'mm'], MINUTE); // MOMENTS + + var getSetMinute = makeGetSet('Minutes', false); // FORMATTING + + addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES + + addUnitAlias('second', 's'); // PRIORITY + + addUnitPriority('second', 15); // PARSING + + addRegexToken('s', match1to2); + addRegexToken('ss', match1to2, match2); + addParseToken(['s', 'ss'], SECOND); // MOMENTS + + var getSetSecond = makeGetSet('Seconds', false); // FORMATTING + + addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); + }); + addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); + }); + addFormatToken(0, ['SSS', 3], 0, 'millisecond'); + addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; + }); + addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; + }); + addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; + }); + addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; + }); + addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; + }); + addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; + }); // ALIASES + + addUnitAlias('millisecond', 'ms'); // PRIORITY + + addUnitPriority('millisecond', 16); // PARSING + + addRegexToken('S', match1to3, match1); + addRegexToken('SS', match1to3, match2); + addRegexToken('SSS', match1to3, match3); + var token; + + for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); + } + + function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); + } + + for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); + } // MOMENTS + + + var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING + + addFormatToken('z', 0, 0, 'zoneAbbr'); + addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS + + function getZoneAbbr() { + return this._isUTC ? 'UTC' : ''; + } + + function getZoneName() { + return this._isUTC ? 'Coordinated Universal Time' : ''; + } + + var proto = Moment.prototype; + proto.add = add; + proto.calendar = calendar$1; + proto.clone = clone; + proto.diff = diff; + proto.endOf = endOf; + proto.format = format; + proto.from = from; + proto.fromNow = fromNow; + proto.to = to; + proto.toNow = toNow; + proto.get = stringGet; + proto.invalidAt = invalidAt; + proto.isAfter = isAfter; + proto.isBefore = isBefore; + proto.isBetween = isBetween; + proto.isSame = isSame; + proto.isSameOrAfter = isSameOrAfter; + proto.isSameOrBefore = isSameOrBefore; + proto.isValid = isValid$2; + proto.lang = lang; + proto.locale = locale; + proto.localeData = localeData; + proto.max = prototypeMax; + proto.min = prototypeMin; + proto.parsingFlags = parsingFlags; + proto.set = stringSet; + proto.startOf = startOf; + proto.subtract = subtract; + proto.toArray = toArray; + proto.toObject = toObject; + proto.toDate = toDate; + proto.toISOString = toISOString; + proto.inspect = inspect; + proto.toJSON = toJSON; + proto.toString = toString; + proto.unix = unix; + proto.valueOf = valueOf; + proto.creationData = creationData; + proto.year = getSetYear; + proto.isLeapYear = getIsLeapYear; + proto.weekYear = getSetWeekYear; + proto.isoWeekYear = getSetISOWeekYear; + proto.quarter = proto.quarters = getSetQuarter; + proto.month = getSetMonth; + proto.daysInMonth = getDaysInMonth; + proto.week = proto.weeks = getSetWeek; + proto.isoWeek = proto.isoWeeks = getSetISOWeek; + proto.weeksInYear = getWeeksInYear; + proto.isoWeeksInYear = getISOWeeksInYear; + proto.date = getSetDayOfMonth; + proto.day = proto.days = getSetDayOfWeek; + proto.weekday = getSetLocaleDayOfWeek; + proto.isoWeekday = getSetISODayOfWeek; + proto.dayOfYear = getSetDayOfYear; + proto.hour = proto.hours = getSetHour; + proto.minute = proto.minutes = getSetMinute; + proto.second = proto.seconds = getSetSecond; + proto.millisecond = proto.milliseconds = getSetMillisecond; + proto.utcOffset = getSetOffset; + proto.utc = setOffsetToUTC; + proto.local = setOffsetToLocal; + proto.parseZone = setOffsetToParsedOffset; + proto.hasAlignedHourOffset = hasAlignedHourOffset; + proto.isDST = isDaylightSavingTime; + proto.isLocal = isLocal; + proto.isUtcOffset = isUtcOffset; + proto.isUtc = isUtc; + proto.isUTC = isUtc; + proto.zoneAbbr = getZoneAbbr; + proto.zoneName = getZoneName; + proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); + proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); + proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); + proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); + proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); + + function createUnix(input) { + return createLocal(input * 1000); + } + + function createInZone() { + return createLocal.apply(null, arguments).parseZone(); + } + + function preParsePostFormat(string) { + return string; + } + + var proto$1 = Locale.prototype; + proto$1.calendar = calendar; + proto$1.longDateFormat = longDateFormat; + proto$1.invalidDate = invalidDate; + proto$1.ordinal = ordinal; + proto$1.preparse = preParsePostFormat; + proto$1.postformat = preParsePostFormat; + proto$1.relativeTime = relativeTime; + proto$1.pastFuture = pastFuture; + proto$1.set = set; + proto$1.months = localeMonths; + proto$1.monthsShort = localeMonthsShort; + proto$1.monthsParse = localeMonthsParse; + proto$1.monthsRegex = monthsRegex; + proto$1.monthsShortRegex = monthsShortRegex; + proto$1.week = localeWeek; + proto$1.firstDayOfYear = localeFirstDayOfYear; + proto$1.firstDayOfWeek = localeFirstDayOfWeek; + proto$1.weekdays = localeWeekdays; + proto$1.weekdaysMin = localeWeekdaysMin; + proto$1.weekdaysShort = localeWeekdaysShort; + proto$1.weekdaysParse = localeWeekdaysParse; + proto$1.weekdaysRegex = weekdaysRegex; + proto$1.weekdaysShortRegex = weekdaysShortRegex; + proto$1.weekdaysMinRegex = weekdaysMinRegex; + proto$1.isPM = localeIsPM; + proto$1.meridiem = localeMeridiem; + + function get$1(format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); + return locale[field](utc, format); + } + + function listMonthsImpl(format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return get$1(format, index, field, 'month'); + } + + var i; + var out = []; + + for (i = 0; i < 12; i++) { + out[i] = get$1(format, i, field, 'month'); + } + + return out; + } // () + // (5) + // (fmt, 5) + // (fmt) + // (true) + // (true, 5) + // (true, fmt, 5) + // (true, fmt) + + + function listWeekdaysImpl(localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0; + + if (index != null) { + return get$1(format, (index + shift) % 7, field, 'day'); + } + + var i; + var out = []; + + for (i = 0; i < 7; i++) { + out[i] = get$1(format, (i + shift) % 7, field, 'day'); + } + + return out; + } + + function listMonths(format, index) { + return listMonthsImpl(format, index, 'months'); + } + + function listMonthsShort(format, index) { + return listMonthsImpl(format, index, 'monthsShort'); + } + + function listWeekdays(localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); + } + + function listWeekdaysShort(localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); + } + + function listWeekdaysMin(localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); + } + + getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal: function (number) { + var b = number % 10, + output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th'; + return number + output; + } + }); // Side effect imports + + hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); + hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); + var mathAbs = Math.abs; + + function abs() { + var data = this._data; + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + return this; + } + + function addSubtract$1(duration, input, value, direction) { + var other = createDuration(input, value); + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + return duration._bubble(); + } // supports only 2.0-style add(1, 's') or add(duration) + + + function add$1(input, value) { + return addSubtract$1(this, input, value, 1); + } // supports only 2.0-style subtract(1, 's') or subtract(duration) + + + function subtract$1(input, value) { + return addSubtract$1(this, input, value, -1); + } + + function absCeil(number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } + } + + function bubble() { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + + if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } // The following code bubbles up values, see the tests for + // examples of what that means. + + + data.milliseconds = milliseconds % 1000; + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + hours = absFloor(minutes / 60); + data.hours = hours % 24; + days += absFloor(hours / 24); // convert days to months + + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year + + years = absFloor(months / 12); + months %= 12; + data.days = days; + data.months = months; + data.years = years; + return this; + } + + function daysToMonths(days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; + } + + function monthsToDays(months) { + // the reverse of daysToMonths + return months * 146097 / 4800; + } + + function as(units) { + if (!this.isValid()) { + return NaN; + } + + var days; + var months; + var milliseconds = this._milliseconds; + units = normalizeUnits(units); + + if (units === 'month' || units === 'quarter' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + + switch (units) { + case 'month': + return months; + + case 'quarter': + return months / 3; + + case 'year': + return months / 12; + } + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + + switch (units) { + case 'week': + return days / 7 + milliseconds / 6048e5; + + case 'day': + return days + milliseconds / 864e5; + + case 'hour': + return days * 24 + milliseconds / 36e5; + + case 'minute': + return days * 1440 + milliseconds / 6e4; + + case 'second': + return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + + case 'millisecond': + return Math.floor(days * 864e5) + milliseconds; + + default: + throw new Error('Unknown unit ' + units); + } + } + } // TODO: Use this.as('ms')? + + + function valueOf$1() { + if (!this.isValid()) { + return NaN; + } + + return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6; + } + + function makeAs(alias) { + return function () { + return this.as(alias); + }; + } + + var asMilliseconds = makeAs('ms'); + var asSeconds = makeAs('s'); + var asMinutes = makeAs('m'); + var asHours = makeAs('h'); + var asDays = makeAs('d'); + var asWeeks = makeAs('w'); + var asMonths = makeAs('M'); + var asQuarters = makeAs('Q'); + var asYears = makeAs('y'); + + function clone$1() { + return createDuration(this); + } + + function get$2(units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; + } + + function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; + } + + var milliseconds = makeGetter('milliseconds'); + var seconds = makeGetter('seconds'); + var minutes = makeGetter('minutes'); + var hours = makeGetter('hours'); + var days = makeGetter('days'); + var months = makeGetter('months'); + var years = makeGetter('years'); + + function weeks() { + return absFloor(this.days() / 7); + } + + var round = Math.round; + var thresholds = { + ss: 44, + // a few seconds to seconds + s: 45, + // seconds to minute + m: 45, + // minutes to hour + h: 22, + // hours to day + d: 26, + // days to month + M: 11 // months to year + + }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } + + function relativeTime$1(posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + var a = seconds <= thresholds.ss && ['s', seconds] || seconds < thresholds.s && ['ss', seconds] || minutes <= 1 && ['m'] || minutes < thresholds.m && ['mm', minutes] || hours <= 1 && ['h'] || hours < thresholds.h && ['hh', hours] || days <= 1 && ['d'] || days < thresholds.d && ['dd', days] || months <= 1 && ['M'] || months < thresholds.M && ['MM', months] || years <= 1 && ['y'] || ['yy', years]; + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); + } // This function allows you to set the rounding function for relative time strings + + + function getSetRelativeTimeRounding(roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + + if (typeof roundingFunction === 'function') { + round = roundingFunction; + return true; + } + + return false; + } // This function allows you to set a threshold for relative time strings + + + function getSetRelativeTimeThreshold(threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + + if (limit === undefined) { + return thresholds[threshold]; + } + + thresholds[threshold] = limit; + + if (threshold === 's') { + thresholds.ss = limit - 1; + } + + return true; + } + + function humanize(withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var locale = this.localeData(); + var output = relativeTime$1(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); + } + + var abs$1 = Math.abs; + + function sign(x) { + return (x > 0) - (x < 0) || +x; + } + + function toISOString$1() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs$1(this._milliseconds) / 1000; + var days = abs$1(this._days); + var months = abs$1(this._months); + var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour + + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; // 12 months -> 1 year + + years = absFloor(months / 12); + months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + return totalSign + 'P' + (Y ? ymSign + Y + 'Y' : '') + (M ? ymSign + M + 'M' : '') + (D ? daysSign + D + 'D' : '') + (h || m || s ? 'T' : '') + (h ? hmsSign + h + 'H' : '') + (m ? hmsSign + m + 'M' : '') + (s ? hmsSign + s + 'S' : ''); + } + + var proto$2 = Duration.prototype; + proto$2.isValid = isValid$1; + proto$2.abs = abs; + proto$2.add = add$1; + proto$2.subtract = subtract$1; + proto$2.as = as; + proto$2.asMilliseconds = asMilliseconds; + proto$2.asSeconds = asSeconds; + proto$2.asMinutes = asMinutes; + proto$2.asHours = asHours; + proto$2.asDays = asDays; + proto$2.asWeeks = asWeeks; + proto$2.asMonths = asMonths; + proto$2.asQuarters = asQuarters; + proto$2.asYears = asYears; + proto$2.valueOf = valueOf$1; + proto$2._bubble = bubble; + proto$2.clone = clone$1; + proto$2.get = get$2; + proto$2.milliseconds = milliseconds; + proto$2.seconds = seconds; + proto$2.minutes = minutes; + proto$2.hours = hours; + proto$2.days = days; + proto$2.weeks = weeks; + proto$2.months = months; + proto$2.years = years; + proto$2.humanize = humanize; + proto$2.toISOString = toISOString$1; + proto$2.toString = toISOString$1; + proto$2.toJSON = toISOString$1; + proto$2.locale = locale; + proto$2.localeData = localeData; + proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); + proto$2.lang = lang; // Side effect imports + // FORMATTING + + addFormatToken('X', 0, 0, 'unix'); + addFormatToken('x', 0, 0, 'valueOf'); // PARSING + + addRegexToken('x', matchSigned); + addRegexToken('X', matchTimestamp); + addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); + }); + addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); + }); // Side effect imports + + hooks.version = '2.24.0'; + setHookCallback(createLocal); + hooks.fn = proto; + hooks.min = min; + hooks.max = max; + hooks.now = now; + hooks.utc = createUTC; + hooks.unix = createUnix; + hooks.months = listMonths; + hooks.isDate = isDate; + hooks.locale = getSetGlobalLocale; + hooks.invalid = createInvalid; + hooks.duration = createDuration; + hooks.isMoment = isMoment; + hooks.weekdays = listWeekdays; + hooks.parseZone = createInZone; + hooks.localeData = getLocale; + hooks.isDuration = isDuration; + hooks.monthsShort = listMonthsShort; + hooks.weekdaysMin = listWeekdaysMin; + hooks.defineLocale = defineLocale; + hooks.updateLocale = updateLocale; + hooks.locales = listLocales; + hooks.weekdaysShort = listWeekdaysShort; + hooks.normalizeUnits = normalizeUnits; + hooks.relativeTimeRounding = getSetRelativeTimeRounding; + hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; + hooks.calendarFormat = getCalendarFormat; + hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats + + hooks.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', + // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', + // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', + // + DATE: 'YYYY-MM-DD', + // + TIME: 'HH:mm', + // + TIME_SECONDS: 'HH:mm:ss', + // + TIME_MS: 'HH:mm:ss.SSS', + // + WEEK: 'GGGG-[W]WW', + // + MONTH: 'YYYY-MM' // + + }; + return hooks; + }); + }); + + function removeNodeChildren($node) { + while ($node.firstChild) { + $node.removeChild($node.firstChild); + } + } + + function updateCounters(rootPostsWithReplies) { + rootPostsWithReplies.forEach(({ + $button, + $node, + + /* authors, */ + count, + updatedAt + }) => { + const $rootPostContent = $node.querySelector(".post__body"); + + if ($rootPostContent === null) { + e("Root Posts Updating", "I can't find the root post content node."); + return; + } // If the counter is already injected, we just need to update its values: + + + if ($node.querySelector(".MattermostUno-counter") !== null) { + // const $counterAuthors = $node.querySelector(".MattermostUno-counterAuthors"); + // if ($counterAuthors === null) { + // e("Root Posts Updating", "I can't find the existing counter authors node."); + // return; + // } + const $counterLink = $node.querySelector(".MattermostUno-counterLink"); + + if ($counterLink === null) { + e("Root Posts Updating", "I can't find the existing counter link node."); + return; + } + + const $counterDescriptionOff = $node.querySelector(".MattermostUno-counterDescriptionOff"); + + if ($counterDescriptionOff === null) { + e("Root Posts Updating", "I can't find the existing counter off-description node."); + return; + } // removeNodeChildren($counterAuthors); + // authors.forEach(uri => { + // const $authorImage = document.createElement("img"); + // $authorImage.src = uri; + // $counterAuthors.appendChild($authorImage); + // }); + + + removeNodeChildren($counterLink); + const counterLinkText = `${count} repl${count > 1 ? "ies" : "y"}`; + const $counterLinkText = document.createTextNode(counterLinkText); + $counterLink.appendChild($counterLinkText); + removeNodeChildren($counterDescriptionOff); + const counterDescriptionOffText = `Last reply ${moment(updatedAt).fromNow()}`; + const $counterDescriptionOffText = document.createTextNode(counterDescriptionOffText); + $counterDescriptionOff.appendChild($counterDescriptionOffText); + return; + } + + const $counter = document.createElement("div"); + $counter.classList.add("MattermostUno-counter"); + $counter.addEventListener("click", () => $button.click()); // const $counterAuthors = document.createElement("div"); + // $counterAuthors.classList.add("MattermostUno-counterAuthors"); + // authors.forEach(uri => { + // const $authorImage = document.createElement("img"); + // $authorImage.src = uri; + // $counterAuthors.appendChild($authorImage); + // }); + // $counter.appendChild($counterAuthors); + + const $counterLink = document.createElement("a"); + $counterLink.classList.add("MattermostUno-counterLink"); + const counterLinkText = `${count} repl${count > 1 ? "ies" : "y"}`; + const $counterLinkText = document.createTextNode(counterLinkText); + $counterLink.appendChild($counterLinkText); + $counter.appendChild($counterLink); + const $counterDescription = document.createElement("div"); + $counterDescription.classList.add("MattermostUno-counterDescription"); + const $counterDescriptionOff = document.createElement("span"); + $counterDescriptionOff.classList.add("MattermostUno-counterDescriptionOff"); + const counterDescriptionOffText = `Last reply ${moment(updatedAt).fromNow()}`; + const $counterDescriptionOffText = document.createTextNode(counterDescriptionOffText); + $counterDescriptionOff.appendChild($counterDescriptionOffText); + $counterDescription.appendChild($counterDescriptionOff); + const $counterDescriptionOn = document.createElement("span"); + $counterDescriptionOn.classList.add("MattermostUno-counterDescriptionOn"); + const $counterDescriptionOnText = document.createTextNode("View thread"); + $counterDescriptionOn.appendChild($counterDescriptionOnText); + $counterDescription.appendChild($counterDescriptionOn); + $counter.appendChild($counterDescription); + const $counterIcon = document.createElement("i"); + $counterIcon.classList.add("fa", "fa-arrow-right", "MattermostUno-counterIcon"); + $counter.appendChild($counterIcon); + $rootPostContent.parentNode.appendChild($counter); + }); + } + + /* eslint-disable import/prefer-default-export */ + const CHANNEL_MESSAGE = { + CONTENT_IS_MATTERMOST: "TAB_IS_MATTERMOST" + }; + + function watchPostListScroll() { + if (this.scrollTop > 100) return; + const $loadMoreMessagesButton = document.querySelector("button.more-messages-text"); + if ($loadMoreMessagesButton !== null) $loadMoreMessagesButton.click(); + } + + const LOOP_DELAY = 1000; + const rootPostsWithReplies = []; + let $postList = null; + let connection; + let previousFirstPostId = ""; + let previousLastPostId = ""; + let themeHref = ""; + + const findPostIndexWithId = id => findIndex(propEq("id", id))(rootPostsWithReplies); + + const findPostIndexWithTheme = theme => findIndex(propEq("theme", theme))(rootPostsWithReplies); + /** + * TODO Get rid of the dirty retry hack. + * TODO Try to discover a way to handle non-related replies declared as related ones. + * TODO Handle posts cache deletion case. + */ + + + async function loop() { + let $posts = []; + let retries = 10; + + while ($posts.length === 0 && retries-- > 0) { + $posts = document.querySelectorAll(".post-list-holder-by-time .post"); // eslint-disable-next-line no-await-in-loop + + await waitFor(400); + } + + if ($posts.length === 0 && retries === -1) { + setTimeout(loop, LOOP_DELAY); + return; + } // ------------------------------------ + // Theme + + + const $theme = document.querySelector("link.code_theme"); // If the theme has changed: + + if ($theme !== null && $theme.href !== themeHref) { + themeHref = $theme.href; + const $appContent = document.querySelector(".app__content"); + + if ($appContent !== null) { + const appContentBackgroundColor = window.getComputedStyle($appContent, null).getPropertyValue("background-color"); + const themeIsLight = isColorLight(appContentBackgroundColor); + const className = "MattermostUno--dark"; + const bodyHasDarkThemeClass = document.body.classList.contains(className); + if (themeIsLight && bodyHasDarkThemeClass) document.body.classList.remove(className); + if (!themeIsLight && !bodyHasDarkThemeClass) document.body.classList.add(className); + } + } // ------------------------------------ + // Infinite Scroll + + + const $newPostList = document.querySelector(".post-list-holder-by-time"); // If the post list node has changed: + + if ($newPostList !== null && $newPostList !== $postList) { + $postList = document.querySelector(".post-list-holder-by-time"); + $postList.addEventListener("scroll", watchPostListScroll); + } // ------------------------------------ + // Posts Cache + + + const firstPostId = $posts[0].id; + const lastPostId = $posts[$posts.length - 1].id; // If the posts list hasn't changed: + + if (firstPostId === previousFirstPostId && lastPostId === previousLastPostId) { + setTimeout(loop, LOOP_DELAY); + return; + } + + previousFirstPostId = firstPostId; + previousLastPostId = lastPostId; // ------------------------------------ + // Posts Parsing + + $posts.forEach($post => { + // If this post is a reply to a root post: + if ($post.classList.contains("post--comment")) { + if (findPostIndexWithId($post.id) !== -1) return; // const $postUserPicture = $post.querySelector("img.more-modal__image"); + // if ($postUserPicture === null) { + // e("Posts Parsing", "I can't find the other root post reply user picture node."); + // safelyHidePostNode($post); + // return; + // } + + const $postTime = $post.querySelector("time.post__time"); + + if ($postTime === null) { + e("Posts Parsing", "I can't find the other root post reply time node."); + return; + } + + let rootPostIndex; + + if ($post.classList.contains("other--root")) { + // If this post is a reply to a non-related previous root post: + const $postMessage = $post.querySelector(".post__link > span > .theme"); + + if ($postMessage === null) { + e("Posts Parsing", "I can't find the other root post reply message node."); + return; + } + + const theme = themize($postMessage.innerText); + rootPostIndex = findPostIndexWithTheme(theme); + + if (rootPostIndex === -1) { + e("Posts Parsing", "I can't find the other root post index for this reply."); + return; + } + } else { + // If this post is a reply to a related previous root post: + rootPostIndex = rootPostsWithReplies.length - 1; + + if (rootPostIndex === -1) { + e("Posts Parsing", "I can't find the same root post index for this reply."); + return; + } + } + + const parentRootPost = rootPostsWithReplies[rootPostIndex]; // if (!parentRootPost.authors.includes($postUserPicture.src)) { + // parentRootPost.authors.push($postUserPicture.src); + // if ( + // parentRootPost.authors.length > parentRootPost.count || + // parentRootPost.authors.length > 5 + // ) { + // parentRootPost.authors.shift(); + // } + // } + + parentRootPost.updatedAt = $postTime.dateTime; + return; + } + + const $rootPostCounter = $post.querySelector(".comment-count"); + if ($rootPostCounter === null) return; + const rootPostIndex = findPostIndexWithId($post.id); + + if (rootPostIndex !== -1) { + rootPostsWithReplies[rootPostIndex].count = Number($rootPostCounter.innerText); + return; + } + + const $rootPostButtons = $post.querySelectorAll(".post__header--info button"); + + if ($rootPostButtons.length === 0) { + e("Posts Parsing", "I can't find the root post button node."); + return; + } + + const $rootPostMessage = $post.querySelector(".post-message__text"); + + if ($rootPostMessage === null) { + e("Posts Parsing", "I can't find the root post message node."); + return; + } + + const postTheme = themize(stripHtmlTags($rootPostMessage.innerHTML)); + rootPostsWithReplies.push({ + $button: $rootPostButtons[$rootPostButtons.length - 1], + $node: $post, + authors: [], + count: Number($rootPostCounter.innerText), + id: $post.id, + updatedAt: 0, + theme: postTheme + }); + }); + updateCounters(rootPostsWithReplies); + setTimeout(loop, LOOP_DELAY); + } + + chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { + switch (message) { + case "areYouThere": + sendResponse(true); + break; + + default: + e("Message Listening", `I received an unknown message from the extension: ${message}`); + } + }); + const $mattermostMeta = document.querySelector(`meta[name="apple-mobile-web-app-title"]`); + + if ($mattermostMeta !== null && $mattermostMeta.content === "Mattermost") { + connection = chrome.runtime.connect({ + name: "mattermost-uno" + }); + connection.postMessage({ + value: CHANNEL_MESSAGE.CONTENT_IS_MATTERMOST + }); + loop(); + } + +}()); diff --git a/dist/icons/icon-128x128.png b/dist/icons/icon-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..31cfb0e47d108f71bc9563012011cd511a478d17 GIT binary patch literal 77464 zcmeG_2SCl=_n+6^gp?GOG^L#;O)Y6kk+heVb_qpR*;|7Wii!wXky!{SQdEjiMp238 z`=9$NLhIG*<@@_PoIan=9p|2V@44rmd+z;w-X^2@+RO}`3>bzn>*{Elz%>jZ9S!`w zIotL=hE19uVrJoIVjIZg?c?R->h8$n7wqlG;~3=XgkeF?)1sYyO4IkQ!`riEP*tUK z-8zxE*0Lj%*5STS$niU8reA!@7e0CZh4>PD>o)t24RaK}yV;4zX2y!Gwu^cYc=dQw zb3>@VT=}Dy)|c@38vll`l#leoPgOR1mDjZ@ol2T|&FEEY%lBq~)3+<)TCA(vufJQP z7T6S;QO=gd&d?EDmW7}7V9v|NHV>t`Yeu!xua>ucz}xe3h<>sAe5bBrP1d1y-=u62 zb;h_;kKTR!s`sjugW}Kc|1m{VyEt^(|U$qoOhaL)jp`3 z5cu-LuGQ8w);gLD3KL8;K5S3rFwJXRd^F;cF7NH#CiAC1ePZ&6Hz(HT;dI8N5c=tR z&3uH9?lli#mMt>#6+2gCzM?@4v%h<`R4*m%T=_-UZE?%|%U=fDerKJ_eL~FfSud@x{mcr_#f)jCzrjljmCkVoaVdPl^jH@y{$9b1vY}M-VS?|U%JQsC7e~BYYDk-+) z?OJ-?VDkgJW8dtSl;X&2sJU>ev^}?UX@k?o+SSps@JV@-j@II*`OZDwy7%JChNcav zX{##bN~w-BZW5-OSE`UVK#EN5w5Rf$4mJUPI2Q$NGw;#oILKG)~+Pcc%R;9UMFRSsso-x@TuH#on7I_3sOMdHKX;d@r7xAsC*tkxuJPv5HB}w68Lo^h>|woqLGe z%*vS};;nK>r7SmUx=hBW$OC!bOJ3()KKQCY(X6yK^;Wp3@F~6KGt2iZ%1aaXd0nWt z*6-l^xu5RFR3)D)J+5`)!PC9Flr)yh+o$@dzbm`)u5rgFwWw^Z-QrKnokgQK_MW+K zS(5jvVwRipqnLMBm6*(0XC#VSk4a};aYlACcS}jhw>>X}ZYSw}d8lWgDN>jkaK~*| zP@1OXCDyk`GF6N1Y1yQkavc?}(rc8&RxvMHl+dhqOF8^$WM(+`hxRE{-wm${7_Ad+ z%@(s)xP4Z3OzX#wG7r=k=nEoT^xvoAn1m8%EHX~frBqIM8B|udXu8Gwpg2{$d*Z9( zv&Y0#mPr?jSE%P0XqBETi;l_MyJE?*uNH0Pw;!o%6ee6Y%8j|ldFR30h1(AY(b$~M zNtpP;P3S~z{Dz$Y*Ob)HJ`cTSaBDo1&h9DP^OB4V4=O5Np6+%wZ@biIZ`JV2t6ElV zqZ^yN-0o#YX0EJVjg0f5k~@0q%pybOp5+~|;g{5NT=#MQ7E0x#$JloVZM^yRhU0^$ z@2gk%73kL8rv8|=V8#*yUs@@zBG>esToFDKmFmYhsYNgEVXrsJY)tojrKZQ=Ye1n9 zlX>oaOiQGQ6pxxQwP|(etyC_BR~Ihu@39Jqm>}ZFm=}KSU6|%sfy|>#?BNS(iwg}{ zlk?x(-=WYfvUb}aURx|`C0}`uy0P*Dwl!4Wif8^D6RgBiP)*;K=d6W0jeG0KK*})o zdlLC7_J>P7-*1|JZN9Ka1gF>0^Y0?r6=_A8*d!!Ey%=SxwNLHJ|MH@3YnDaayCb2L z_a_{FxFGCE*51jtR>Yewqo)*F%wHI;&EufxaB&y6e9~9-wjHaU6uJddZW2C(TXOr3 zVKEac6UKP$rik7##=8e=c<6EqD|ee5ma}_$EZF!ocVwjNv9IUt7o~qbl$&tbE<2f9 zy5yAeA&KWDlP}yeQWI^IHZs=umOY()oBd5a4XWD@;#C(apHd8I+CRt2v9_|FnO{p* z8wmpd=lp6kdR-dU7&)Q?PG8{C@sdSCQP#uT2X@$0rH%(wZLeT$)P|DJsdm-=ID z;e4(e7}l(Gt==5^(EG?;7S;;RXDk`ayI-=TPRO6LHF@FnGw1otV|aX?r*2rUpS(uV zC+F(vT_HQwP8Oyb>T2q-UVPfPjX$0th>bS?S?*G!E5$illn3I@Hs5UVRh_zJ?@gRq zvWy&;{p}AXEfY08rHw_X{gr|@Xn&$=yrY?>`s{=X*KM`5SZmuIaa6|B%I&Fsbr9v9H zYUAB`p6|{-tbA+f;^HgUewQO^+4xNhxv5tPtj;-}AHSCRT2^s6yKZ)s;0nq`8|?O% z-MUguBYr*_V=}?96+L}rBe&(z2enx~I&^;eH;yKq4x%)QPusm~yVAM+9GOQo-j>FB z7&eEQsmXJ^EL`_Qc;(ttxJXx<BYRik4#*|EI%Z)9?weV$FE=qZYeVDz;JlslTIvr-@Tm4e# z`Z+nxf>@4}TXe1qUpa66BrCd2bzUyL%2@$31Fl(YPh3pDm>Q;NM2XRS4%j@#VsV7& z8r@I1G^O*lD|`yyxIUs%f6}vvBL{YHs?$-rcx%5|(L@n9v+g~=`$xl50#)~z-kuE- zx{%Q1Mti6zP(wlW#H~H&JX|s!7jJk~?-}_$W${%N>fm=u)#qNEc2uy?G2|@;|1fb6<-wuZ5(5JDPH;bguW`-Fsvda;IK zx+&H6Nq2UO>^&1|lk&|Tv$i(hT)B9OvG;4?)Rq~`=SrLyugbRKvB8O~%){HibMFsx zNT--qqxr4i+;;pP6P<%wL$oSdpK!+J=xMeVux77J@GG{?S%(=3r4@a&e!6{q32)$K z*Agp{Q`CxnB@>jN)J%QK=r1IKI}`4)m{sBCmVDQT(~KwE1eDZNZjFdlTD5s@xMB$X z~r`)dWsp8CMo6)Ys zvuYz#h~>@%Zkxyn$_2_ML6uJ&^)|3LPTm>Ey0P$mP~B0lv%H%8yVo1JGSVi^^Qb;n znd&l2dBb7#B^*11BfaV9zeuSpwkdh#Cs!H&aay)cu*qZz8tjE*kVx!?nRmyhYnB#N zUDs6K7p8ppS{Q#m+df>e8~vE79a2ZGU464kGS(`F;cK{sl(u2jL}u*eriJP|ST5LY z-6Nv%Dj{NA0teOl2~9V26Nsk(yiUOi(%Y_V(+TlH4kFHD(ls@7KTV@s4yx@UMZT%hAJq?Ea> z`d(%C3c6-f{hFeJJ*#}SeBj|OnN_{{uEjyO^;;>*9UMa@TsV1)m+{4mmG`|9bc8l6 zsF7jxWfgRp zZ13EsL?7AErfbO8jQD z%l&k~JXzaY%jq{P74y`mO*B?2;V-=4UR-M=SU^qfYvFt_Zt(%<`yAmf#e8m@z0T@z zPoK*+y86tF*$Xdn2`>=bF@Jr#3_B}tK)J!?(~eI#9=-{kalfeXZK22#%9*r_zK#8$ zDSp=UaK6O2X;iccRmUhcUr-I%AY8Lwn|?yJdFqCpI|S$AZAASk(;Zp!7f_3t`D!-X zbBGze7CIxTcBNP*fl4bm=By@R>{xY zAKms?G+i)%)!Nuoa>dK`ZeLklSI5O{dE->G&o%wUW$fmf*R4&Q7w1-KS~r_ioHJ!o z+!!INjtL~lw~J0W-x}(C&Cy_O^x}4_dh6~%UrInsEqrq0E=9YY zSsjmeIE&8{ddOjO)Bfgrmetl`ua*>A9GS-SESr|`@kJ4hi1iUsN7VC|N!a`HOu5&% ztL1gg)t4t!UvH+kD;xfqa`Rm*IopP6OL5~v?I+S}^ui||b>*G1#vrY&Uk zTd<6BL#F6^sEO@LQ~pDNiTN zGRjH0JGpj`%)wkvmCB=!Q{HGVmdRygEsNpDJi>LPx6@Sx3UHsC6pW9Yzw!0AFVucK z)34F5NM#*=ob!oAT&iw$w%;v27Q;nVKQU6 zb#2ADOw~81%Br~KRmu`QEfoSLXs>%_Sl>dq;BsWCY2ADZhJ&iyo>q+4-!-u{(0r|K zqfi^`@1s$EDQ8dq{C1b!Opb}#2IJ53+~&W2d=}OEW6Y(lyp!f^jGAfytxjwoS=??8S>s=H!bctAuz^pHdT| zE04J7@!YaDPxMm~)24##3+!?C)^ID{$oDqU2&ko;oPqhcSOej8t%JsI(}7qtJYdQ zV_o>*665(&Ti<&6n)!QqZ?2@1sWB*jeD-Q}#X669PhJ&Ruq!9~e80`&L2nye{Zi@s z66!MT^xVq~Z|`Kby6kFhuy`3hB>_{CT*AMFK5f6unZVC;zP@3^wh3r&TmGO}uGH|W zE%O^A|46gr8jEIqV8Y&6JlpG6ce$Er|NF#j>K#icww9$|5_n*=d9uEM<~#|Pg~}NM z3&-reZhWn&cAEnC67?@}7Kdo0qND55&joD}3}wnqOrZ^%Z8ceCa>?Are3~1cyYih6 zYQ3DuGre)rvBC%y9tKwTH#$dYFYaUe;!16?I%_ufKF`CZw}W0))JX`r$(1=h<(WiN z;2v={u;V6Yz!eE`OwhxcHI9)~Lthr+l2DFh_TN0CX{cVm9B=Y#lyII9IEOPho?#`);%)VjrK z5aTzOo_C_jVGimNL(Zlb5nNQP9f!}vl^$5VVD>Yi=tZ;IT&+2bEHfzfCmy*J{w`y# zBlCw{QM>h@E~Yqie7wu91+RAQ+d?N6u}feo_x{@%`tv_eJ2BPJ%}CWs@EGrtUFHX; z2kytT)Tf)$ChmMV$@aLIwWlS<olad}uZLT_`4A?h`c8#)?i5{RfBEFowJy|rbm3e0POCP!vMy-M zIlqxo*sm(hwbbXrdP{X1+XIw`e3+vs))n5)iI|b_c0qLA#*5ohuZMeXNPHPoY|8vV z?earC&5VK!VT;FXT;nBv&k8M?1OOR>fl(t%s`b3 zVJ;L?cN)pg#3t-0x$Q5wKWw-E20M$zvbcTK@ilJ6JM(#k=46KiMzNl)axBy{kz#vO zb~3%NfuX+La@$VTuQ97Mjs&GwJ#>A5*i<2T^GKN6CdxzS4^4U;Rbz8ncWUO_*@^PsGfpTzj)>>7 z+CI^0i`p~e15a;q@#{-#2n(vLQf>5=+{;{Rzu4fi%h>#_*{aj4=e4X(8{4q%_UZD27saOSrt}+k zF|nSF^HQwenyT_k2I}XQ#5vfNDW?dnYrLkIP91mP#nT3t);qlMyACTy+z$x~f1Z8W zG(eFroZGvmBA`iV+^Y5YZs+96OYPi+uJNc+H2NED#MI1|vY80QL^saRJ8oZ`q&FxnnJ0&l-DMP3z(J?D3a%<6@=d`Q9N*gdoo?Ow9g9Du?XJ2ed^mlqg|VB$^mAFJXLAjC z&59b!r5>^e)RFvU!pM0cWq^y7ZBs+tHT2kMELAanzok%{HXe*ZrlN}rR40+C%`31!1u&9XCQYuNee>%-> zkB@n0TYFK^n`^Z)_mOEXGfvH)m%E(eY8{3DTis0AxZrVl9K5jV z8S-LUgw4wGu~MS+a_X-W@3W>vdF(gR)n9yP%EG6z-gn;Y`eb=Q%*k~!otoP7kP~*= zkq<5vhz7*7Us0`zKH$7xJ1UpLzR~>3|;d6a^mIw6y}ej8`Vy z;EP(Mwe>n1=MG#m=hgt8d4`nP#g=?yAHAb(fA#t9MdvNKG6(s^M0Bj)(6F94c5lfp z@qNw3#cZp0<(-$%=Zu?A-*i9G|7kpJQsXv>XP&bS4aHRI)wv(ET8LceSgv!feKF^x zVE45LMH>;Nv8&fP-Coh&;9#pG`!FcaBIIoPm2DH> z>#VBYsP_na^R_a??ch@N=yYMJdHN==tShM)8?ElT@*Z;1QF`p+!hJ6%icZG(F%|co z^_uIy<5DWV$m3MC$8F=&duy)kJZ*9A-p}nNa#)b67kA{kJKI=l)^F`F86Wh@l6|9y zhS2Sm2a{%$Z|?<-zYoptC@@I>K`8hZH$=_M1w(#G#y^GO3+ zb7t)wzq{Vfn!BgGca2`|*0%D{#+rB0g$2_@loxC6pAvn`@I=zxRmQ>_(gGXCF6bQVCNfo;l7DnLHoAU;q5Kg^AV= zABR0|o7(QRX3Oaha+w&0i*VJ@Fw)h~=-yd@{gl|1J5+RTs&d_4YI;sYj3r>~@?0Y& z%du?BcZ*ECuI?&&_Pvcy&4&CVyt>PmPq1QSSvA9)+bY)I-rUM~T8Qa&r`+jM| zwo`$U2j8r$eZ*?QAV3+)_hm*Qb5u}VP)K2cLf!ZcmX;4>&OP>SJJ^)HB59qXJVhWqMn_G@ww0X4>H=@ zv-x)Fs6}k%lrsun$C1VbK8hlsYC{bnx*A+hIRtLGpI4Ip3$Y)fUZ|KmUU6 zb@}{uyBAXvRc+W^iac6di_gahhT$h&D0trCM!CP4KdZcmPdhtX&U<-TQI$%C4=qPX z!E_BD{y7E-7F6Yrs$=T2E5!1zy>BXdo>N1){piWPo?&Y>corT0D7!82TR>A&-2wB} zb3(m*Qk05iY%pw`qATolSs2VywDnz)Qeu!o%s1H6&o)TR({~yo z(Mdzo(bwL`)!Wb2%aaGuw6*i{_fz5HgLs}U;t*@E6$F7@1)ygFd0#&Vab0+jf%-rK zaVZH2c`*qoF)0P{p7|lxz~D!2Pv5Rqg!U8eZBmB>>afN96kM}^(@re-QTxonf|_xD2TwfyMvQBFhwZ2XC7@`1EU{#P%}Ea zdUz9ZpwvB6I@te6=k4#~PDtZmFYf5>=mCuQ0%gfx(xZ*hA31)h4~qGN5pNeSKQCVw zFYn&-{D}S|qo1o&ALXE!KaxYWdM}~7UkG(3^q-=pm%Tr#oUWz{AB4=sN)qiyxhHfOhJh_s_@Cl%1X=r zj52Z!a&))Qgn~Ugsme-7{uXQ5OY9HX=%j7nqMF|;2NjXsoS;a1bKT>;vMeF6R!iPGC2em1oJQQsJTGGMR&$cHy88Hc2L{3sc zQBvwRa?lE{PQe4EMmmv4xl7wA&hxS-v{EPI4ur@~m8ov)EZ&(`yuZYMP%?G#3iKQt zou5g6P*L;o3-t0?X6R#R=jLed*FT-!691rN0+W@mpHHyv0G0YJoien%fq|k9JOnMSXlvgoYxV>Ia3J&{v~y>qYcCpM&`RY86<;qWzd&0b zM>S^G)eOqb?ZJ~tl*-QD?wTVjV)Ayg6vUinDM;E&+Q~~w z%XN;(zACK^Qx##5@CbEjuf8g&ASMC-<;)~y6=kGhtnhVJPgxwz|J|LbjAqE+x?35| zpo+RkjhXs;d%L?j`ur*e-NT}fbUpGDMwQoq*?T7I%&p<&9Sn1Ti=SbjXTQbwlCYD) zJXd>Asr{DSGf8K&^e~g4%AH|get|V7{==N>8U)ZoBMDuDYb1-{;rUkxQSJM$x&Ad5 zQ7u4J;(yZhuepe70iqKBlP;1q7sF47kfSHqeSzTaDPAlp0Inh$JAG|U43GZBXC>`| z5PEMNOJ59Q9FGu(MaObLAg!OSffns+dKzX?CQ92<2@K=GbT!q?f^e8>*tOL-JRT3J z{x{&mM;t~=i|T@-!!W!k+)M+U0>}l(1~>tb6>tn7C15v1LNi2PJb1VeRs8BMT@EI17*;aIkO^M$-Zo=H`yUX82!9_n#5~91e$lsV6kQ5d75w z)B{ulB#e8w5(^JNTd1%wcYGr@{9&>d)B)E1DL#9f2tdgIns?9BLaq%!)}ftFfD1HwuRMs>q~$(W=dapMk|92)V^ z`AE&D06quw1SECm14%5Py`7Yuj{)DIV3Tw_0|BT3GsWul8&WAM#O}z#sB3`FUvL-& z1;z)}+yrP0*mHSC>e|P2bYMaK2EcA%1j-qJy>&iG3Izc})5;4vI=u=S zY9!Ai2O~NK)PaRhNrA}$`)Pn^Lxz-qhW1{txHHLRao0C6;6SUyL%B0ZS&?37O@XkK z@88c`egBR-3*O3Jl8`27#8v?y#i;Y`fz8{1r0RTR#G%nHKt&~K01ZRN&WFCoz6HY{ zv|8y8z#-I*5)TKyLT0pMi8RehvspRt1An0C1@3-CCLpD$dH{5r6vImX7CJG5Kskw_bOOGn{t6I zq7N&Z-{VmFA;VxQG-%?$AXxex7a#*EI=>m{1VWp`?%lCb>U`w&Tg3u=AghcSa4>*2 zvye6%4%GINSsCcwhBh9LVFkTJ4=spf0sxFb1L3a&8)`#i<(FJf;Yk{dJy^@Pw_=#( zFOlSW=rRD&$VVE0oY0s50t`|7&H4uMNu&}2k_bTO$j4uW7Lp-BE5*TjUIym;r{uEq zd*c~xRDl7w9{%X{7T-@898?*uJ%H;^&7;k;tojBC&;-MWVG97v`KZE3MGm*~k+ts( z=m7KF_u*G<=oE^cp>qk?VxSN-L@L9y11JWnKL`On8wMVlo`wa(5`a$2zvC!ypgJrr zFsuRcYs0Qx^hmCM2g@TD7r~E#Rx?8dFocH#IJ5#9NC?n$aBjFOg&_+7TJvLA>t^^f zT!Zfu(3nk6Z;(aGT|1yTB!GHxLdKJT!&rjh2Wv3)!6O9{fc~a|?tEYvb{rax&tOOb zfV_PG4uG9sHt1%D_$%ssH5TUO`P5Wrh|f*p9Gy#8Lg!B&CTZ&7<)=ad&@@OI7T_~j z**PEwnWIOtAqYSk^7hRF8vAD&aJ*>GI zha5`g3u-p6qX7|blx7dL2G=RwUvE z4CA3gdwVrHF*R5X&|T0G*hi3{p~fn@0|s*?N&|GdNAYNfk83c*`$&V-n?1O9!MQW~ z@cskgc$zkFf{v$=3YdmNC@YJQdjYDTkYWIb)A?wvZ}InZJ{{B@p9nmWy7Pe~#)$q5 z7dkzm6w86m10ralK8>w!pc<5oHlP5Yle~ERr=>ttg9s*iOX?5f{#9=gICYLr#szKXMWma2=L5 z(c@T0f8MWpOK|hf1NOs-s{&D}QJawrSeV0J05M;p2*wvm>is+muwv|3Z1O<)`xS;x z!vensh_DSrsGoQ=Ke;h8eHnd807h7t3F;r6T^M+%^i!z;q6Vdk2cXd-dNnK&`S(M> ztsa2`-J&UJOWo)GtJ$vrz`B$Nh`0_^(g5)X#;{;T1Ee8KG#G$r*>oC^q@%SL=21B$ z1tvzM5C|J*XajAqU`|Qd|At+k0?;{UVi8c%aOO5NhlT$QUngm390NlEe+2ju7;Nhe zBOOue^1+q^OKCKab`Lf^q(j4hQ$r(bpK72_0f4Phe#mS=L}9%p-N(WlSkqesIm3`J zDMyhHXhHdPt zY%+z1qkVo8C@hpr1)^d|vLx({-}ZL=M+hf&Bc)GAQLh331t7PtS#Jyw5q1pr`ri}c=xgV8q@ z_&`SAh>b{8(O!V5%ZBPDYWP85Q`G^LSRyF}^tOHchX7De;E?Cffk@)NCohG78@~sV z^SQnOy}3(xr5o8YL!XxKZ#*QPyx|d{UrH43Tbrf6RE$l_KN_(=@^vB z?f0BRcs_$+$dgQdK-<^g5l8lmKlw}lQ6kCx06!>q-E?Vz=-#Xni`R%gBMHC*d=(gW+|g($K-ubHo9R!EaE=Wg-i*?CBo<(b-*%w}ePy zy(PcKHF?zB{u02@!rqu7bJ%cKP=jK(YZ^E?sKh@LSyEBKOGaJrLjd4;3ZQs*#1OB@ zip(2g-eG0y;k@cur(x0jZ)C<@06tN>4;Cii@$Y_213eo{3n=t_9xTD0={~?iRnGu2 z-cNIdv^X3UIW^P0KKSS-7_WjNyETA(KPiccdQD7X5~h^`THSRaA=&>5DT<*S zz5y*jXtcxVik4EO0K()%3PMEE5GFGHNGFFSVFwvC0Anjuh*(2h2HAlW^$i5~EkPPc z&?>}us7O%U4-#lK@HYY47$SpPsI$rqjSa{QCsqLDk>iS@%UBt%F930Z)}_tpW)xt; zD3sY>k>IVvwe^>PlyTIZ?>a0J2s3H)hGGZhtGe_s2Te zwQcV`iu9o^ox|?)5Gacx!%1KW8T-mYHnsN~17Ci79_`0UaxDWDrksi?+t&uodtB*dK0?Qx6aO`Q5u!zw4Ut~>eb!6Z zXa?Qt{7IzIWMNQcPez@_HmIb7OGFB1(%?$^HPs_{Bn*RJgGc2FW@KD8IZHjwj$A{;4(vKiHSF4IVsj1DhREMYDo4XWW&IJ)!h8a`#})ySr&oS*fZU>X zWRr%U<#ye*Bk$gj`VwUticj$m7P7z;0<+SWOzz!K9Z$pWK=-3hAIFJNB~IP zKs-Qmltlm*yYQ>h_wHe*fEP)?EI?913lMV#^d9YBm27RzMc=|fbsP$OLIQx!d6OCp zNKJ4k^fWc_@Wm*68RXRjGzBae3Z38bT!Lq@rl!B+M-adzt_}PQbyx1gNC|-TXgLUe z>ny?}TBib@ga>gzbR7C9ATgQ`E%s4<4M1(6^_+u!^!FmV&ibQiZm949oeX(9)ZG2# zLx=Xz)a1QHi@eZX7zs+olB1%7B7^+_-9H1jN$Z2v9c6&10 z+VBm3!v_(8pC5q3QP6@7uk#~-_?tIK0A3NFZ%{ex;0?u`zvJuCzw*m7l^_VnS8xM< zmgC0LB6!u572#~Gwe=;|)btu_2H%P%yoB`p@#v5AU%Bu3)S(Mc!1<8j6><$ChyL>+ zlju7m7)rRw@Jmt1UHA`3+yY4b!}-2UAUhllpb3WrS&^DUqk+^w0|p9wh-f9L>Heb! zEdZTA6)woQ9S#&B4S)c>Ya~s$BkdpXGUB*E3w$Ll+5g|vx<>z2Xocm&Xo*_LJD!4t zIRVjlFbqQdWgQDzAY?c{f7KuH|F3b-p6FDM(=h9wi%zn_GSC{)87Tokw7o&gOhPyR zVE8T2^>uGF@)?Io?LKmwBR>EFSn7-zptDPn-@c>O);}0-3&3d*G?+-S*>xZBLilZ& zt~uokJfn5+NCEto96o!bi2pCsb=u$!BmUR#0(3dr4nn z65`-A2XeUlgQ2&80%WxrdiEbVLHpy;;P0Fcy1w{u;Yaky-0(r6Tf1DDBU8fvFx9S~ zLXCwgl49Tee3ysxhdqFrE(?&<=L8Vlp5P2?SwjrV?-};*et;I}95fx_kW6HNq=SwA zq3wH40Tqz@@n9(oF&&cL`1%G(UJT0}B8mTR*&>kxNEK=wNTQn8fFtlne^S9q9F8leC$V2N0Q|Bcird>W!3f{mVc54F4UI_4{e$in zX#6Sww@o|X&%*975?%LaUa0zo6u~LfGX&P^;KjqghOlux!$wg&fIm`iskQ*ksbK3>_pJLb8URIfbP!&9jp><)4EL^h{D*|jp93L7 zX@6-E^$koo==?3f9;rJY)fm}#zjQtd{6hnvKyW!uhD#YBGD64+SAZoma7=w6_uH4` ztYmLxfk8|SHW3hx`tu779;~Bv+XT#{f*&F@7GyrDpuOa$j;2<&-N!}vR zZ{9-Z`#`D4E5|c}rC-P4#@*_RexDiuWdJR}1(z3qbm)1M;4PHv4tT1|TRBQ>kfzw` z8XU&JKzLU_8YrrhhH9Tw(5gxv+6{L9dWSwW07?$;+Mz|`p5C*PEfhHkP6C4a7{~u# z-AzO`4QMku==>0<3wp7z&(7a7SN0WB3c8wVW{{3lkjBEC(x)JxLi*JPC;?OejwBIY zyJAPrqYQ0OK5|-Zgz4(tf5TR|32mr@11FC;@VyCeDj+$a2?`MgO#p(`H}tCwP`08X zJUZ#?-!}=e#!x|No`B%q#I}KUm9qbd)6gYa&DUi7Fpf#<5 z3ok%&c6xWki{L#{arlx6YM*{#Py&D`K*f0A@&s_Wr&NK&hyZe89R)msVGO11?M--c zy{^`I){^l4o+gxU2Z&zf8m*&nXlGXuRR3ML4hVx507MCdz!@(42c$as37!KBmjKU! znRDygH+&=f3@Jt`f#~dT8kjy?IG_w2zj{ z;YX4*q2tY74+h1_$f?4rI6v8HOzYsAO0ffYSqi9d2cZ%*nru#Iyi-`f#w{ z-vLY6;lXfhfFC6TBj11_4G75l5%}+Bq*|b>^Ye$@`G`T12mm4kLICSf+#I;gM$i9X zL|OoxSZL&<&Yww=0!T6i^yH-T&6bX15N6Ud{NH`wEnqBV4h|`z&H~&3K`1;B&7KV zeYe00N=mWCFtA$sPBQcul1~RcSwSB?g74m-ciz$fC-sc`cRyeY)Io|xa0=?eNS=Zk z5e?8?HMBj+!n_jp4{+iTmf0Qt?>b-$fU^gaU|=vF(auL)jHm|aS z9~DnF4bZc$4Gke5E2kO+S=I`s)OsyAqum0mlSe&I=&S z9Z&*rRBV=Ro`|@jb6O>UdtsJ61|Pxr^tW|9=Ag*gN+>j3{=_zwuc&&ES<-gf;8iU5RaccCU+X@907>m9P> zZvdjxQOK}+Tms`>R)+Y4nvi!?;6Eh*zqe55G(ic*V!Ir~p_577hy-LLpc06pSFh0_ z82BbX?k-GGO+z`EI}*$dh30=+0DiA9`mts7Iv8{eJ#-9OQJ|?}3gBcwHo$R!=%tS_ zfW0j@(F-GA0N(?m``3U~fTck58PIHirQ5JyHxrdUQ3Evhkoda*Kyr8hb1EKx{>mh! TXqL+a9j2=_U-P88&6@uM5Y)GG literal 0 HcmV?d00001 diff --git a/dist/icons/icon-16x16.png b/dist/icons/icon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..82f3c0c6bd6489a7388d345df1cfc51f465217cc GIT binary patch literal 7341 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 literal 0 HcmV?d00001 diff --git a/dist/icons/icon-32x32-bw.png b/dist/icons/icon-32x32-bw.png new file mode 100644 index 0000000000000000000000000000000000000000..3291e535db63557d74d94282bd440f5c3ee53bb6 GIT binary patch literal 8453 zcmeHMd011&79Uc50*XtGC~7stjiT8XNF*S#Mn$4PL40k!Np3}lA)XAk(iV&3x(06n~O6H_cR5i8ATGN?3KlxE2>qBJyH zqXHnia#!-~{a*(5X;V|xo@4z(7QIBzsP?O>*+|jM)@6oW{-`>7)accLlS*ejY5!_n zSa7yn{pI5uo6Q6J4%6LSxQxB)WV&Y0A65NE6d2!WF1+n=e9Z1W*SU-#~ z?UwyGYX4hq<@pt@qbank_Nn17zwQfocYk$p0f9FmA z9lCLq{Cv6AYiVmS7|RbjS3K#mDWOCojPf0|xzDOfxS_>z*#%};u-^rzrYW7szsNHk`5D7(b_B*rXCLoUv$K zr1!kg5li)(UK{ekzPg0ve>)?&q9{wfCK^>a`n-g5IbqE(ztH}#7gyfr4*vdnR(+e- zsV!|M6A%3(j7P61I#VSx`)S|2o!|B&XT+MO%gutHuCASzJpWO6ROx8@C#U8w_`vUK zgQ0f#l-4nyKqYU10%)O6aPm9U;@WYdBKi{n`;wM+XlYeH%@nyoW)dlZ2 z9yk#8fNMQ|uzAGw+w~a>A5B>i+A!t(KyJ&nlIwdL7JQ^mW!>fPY4;lOX?gtE>KXe- zF>$U+zi(JVt9GB4pBt2uD?bwP5{*72i!cK8Lz! z#!W(@wFcJ7OR% zzirDnysq&{$g&xKU-Z+#z}_vJDYi*fg-HjILBmQvduu{o|En|BMb(bGt6vqp=v+zR z*ox+p6;&$1dFGN`1aCk`%Wmb-&rUa zd3hsJ|E>SdmR6k)@4MWFjfOVL=1*mlkG;Ff4}gJw8dybB;--le1|1Vo8ssQ5TW5q- z7J!hjY$Kw`KrJ*ms@CWw^gD-+(rFr{gq|#jW5*dI&@@eKt_e-Zot~)3%}|Jx^srFx zkZdso(4iKDmaWt3&Ejkc9mf?z8e_BQG+f1!A)%+l$!HM<6H4PV`Ajw=DqEAqrH6Xc zLQG1PcxGfY2?0kEdYZ*z6th@XtCeZxF%2d)iz5<=SZpqf%Vj_fhB-%XL9!Wo^C%30 zz=%Z63X{fY(HQhJ3=@$XGA$B19m;7WIFu@)vLTb402|}*W{Z*~g#$j^4^&`r+3a8j zo6F#eSg!U^8W-oZ)|*K$LVvQd5hIJkWV3WSHw&{RDyw6@E-lQ7@G@h~M9qdwlLC#( zLiLtWu9F(InP%5HGtDT*!q=@;s#tJQ_{^?0G154h(*|>+TB9@K7MQlHrc&Y5GiI8! zxQ$iy}$jg-(KhpE&k#YhlOA>yf23?4_tW$;Bj9z!k=DH$A|oXcg4 zxGIiP?gAmzn=Oc5fjS^G7=%bD2u6egMv#!lX7E)?K0~BJQAUu8tCS;%3gL@HE)el1 z4a_t|`yZ_aJ7;mYOe&#snQR;!=g72(MP)GQVEStGN`uwhAxhNf&;$#Dxr-wZ28n`% zq97hm#ODNaJCt5SO=g%z7%GR&j_i=o6|`;s|%?!HVEuEgAzjXa6>Ev#L$885D_fj;a)oU zSSD#RF?Nz(0~brI9ydwpkV)u4Fv;0$76*HFSkLNK1%`__!h|9gG!p(pY&J*8VDlL4 z;6yH4%;t+Z!trc@m;`ic8%&7?gH}Sv4u^*M6rT?h$H6M8L@bCa9G}4!U~n9fn8WP^ z2fd(C<@}j8RugFX2={0; z_}xLH;ZGpP}bsj~5NYpPIX> z5!Mj~V-CFH(k$^-eYewhp-3Q1(Dui2H-U8v42_AgAgfFWs=i4foxH|X%LC7){35zuxa+w*@Lb9-qU*orF7J--yHGuRt+m2$ zvo`ezo&>)MqsXVmM1uCk1?5NK$jcZz%M3v8f!MzXShs!%WcIR1NC2D8M(dDazun-?J`Q{bhT-H^przg=*|4*FfiD2&PDdLHPTOOs7l-0T@TE!NI{uf`uEl`@oMveF!$W7)U@V%(ZSB%+O<`IRM+KEw1V8FslIw6^rzzS|jK=8?1#H zKr}}>Q*VMLZn`7E5qqgU>b8d~*Zz`S*7F3|>NE$SfLetY6u2u-P)61yR~sAjNF^*b z6fhQkLOW&0&mai%7I`zlqI!a?imnjPrkkMo4NOdiGPM>&fcj_acak)LNW$C+0Av3O z5Q85(DRw=qfU{RPL>r;7m%DnPk51>)PIVnv7v<_hGE9u zUT)K%$DwAR2cOdT_*WQaU=tr0B%8*L!HFdzfiRqplf{YoIDV{9fMKz>_Xb5|J+LzQ z>xz}2x1LtgqZhwO1^S}*Qr%k%M&<2lU=p8N59K7w_T`P_luc|ims=ixVsQCg$+-GK zrpFWBRGSCqa*L}%O((WpUVCTmefior>38=@?t_HiE#uyuOR}6}y8o{H^|Rym58w1& zxb?5IM{!RtADeyGqhay+y>UeoHyro1YO257>UZ3pDN1bnbMU-Zi@YUe#s_2-CnKM` z?N6eZFMB4c9MWVxAhqdcK+Bmc!B-uy*l&yP#}qjD5pAnncFb-v-r*oRO-=0oOObok zw{}HE?i({CHFFs)Zt?vFUo5K2(F$H*7j=xXPt4WLrdg)PQd{+dbI5ja$BQpDpJ{7uJ+Lx$$nn zLQSJH_UdNzZW$2NaK6Y;FPu~w74+18YA>e0&YLo7_~T;hLi+Mo+IVgE)RDi+oU-1Q zdOjfxPf6=NAi-d`p2@g}{&;sw*JZ16>VG|TW|NMmU`qDUkv@)#2lU^uMq*XXcd_U* z`dkI`QTC+L?Pmw>nJ)gm)GaD=*S@V~7w9*FC%L|(-E~P{K70Pr%m!9eE_R*!cvE}> z|JD!w7Ktfl`YUKJ$0h~!??-grwtr;#H0vsx-E(Iy3~30d`crVpciSt+#QY_~dTH<7 zPe+aonO70lr)=h6Cnvi{e|l9d+)*(u#50f;%V4dW|pn+%R)D-{RoW; zcnu7gj9(YD&p6>lO>%*a<=CHoI~w(TYOHpvuxiPp!n&!8u=!%9QNEsyORveVOIh(22`vqEk5e~J z*3~+n@9pu7v~JwZ;9f71cV;zJpN=Va^_fPD=u4`(__DgViYhJb7bc3Wa3B1;vEG|P zhc^wm(ZY>6w}*|jn{dqvpHaU)-?{`_yDoOzteE{z%=VO9I2OzrS8D8>uvJELo3zuz zWmu}&K+J#hoWhIg_i@|Z2Oi#cP21%!JgQs`a_G(haK$Dt_W;Z5B*@qPH{i-i^H6yhg0d!>Nxprv1We zz#`ic?kY1ar)Qya-BsUkG``ph|GSK zeUpABWA8Utb2*;3uM1r=a{J2J!#53^F}!hqWi9PzdEExvX2*)?iX&-GdKc=`*X(n{ zeEo-$WZ1P$=aIEO*J-KAyiwpA*Q({Wd!6K+wh2^c#9^{ zEjnY0FBk3&pY12yX~>8!-E`|YEq#`ubCBpTew$UDLvqU5kqOW37Ox=%r1rnL$|Yr$ zOAXd{XMw@K7DM8~>{v_72Z1YVQ*468Jl4rM*6V(@8TL)y){S9j{C*j6bL1n}fJ>Lk z?M4`HSodSvF?qkA`b`;TWM(wIc|yg4Ex|JvF7{r&=9}!Fi=NN&-;tQmzwxBBse1Zq z#}jR*A5GcnRH^f*d*J9KYeNLlury*v9*|F{r3>xf~F=j#HWw>K~FYwvBCP$4U> zGjzFWvE9Yf*fl-%H?8|c)zh|=Sr!$>$bD|v{a%04>qyIm#oO1;HJd-yYu7`n|2K(u zDpwO63KDlYth;@^MQ?N6sN%OR(U!Vrbhwjk%8;;&~nH9m#j$kjj z@#~s-Py8%$?|Qi9zCV=wAz9DoEbp>_YZ|)f>xCJ?Ay*cJF&#@!Jd>MSy`cssE*l^Z z*jZC{zfZ>8&}oHdb7t>+w=! zVXvtv+)Bq$d$~#Hqt?63xFH|FI(}#t7Wgb^;GOftoJ%=3p3lJhH1ApRmQy%s>-&qd z-Vx^2zk9T#@tl0m^nR5dHWOuU?-v)fRo2{HpK$3~z3GRF9X9d@eTA(rU&SwH{=PB2 zwk1~fp89x3|EB!=MvXUuuiQ0kxr%K(wdnf~T-Wdq0nWKud8d{id-E!+^nsWBT*0!|klU-a2(23B$Bfgs!gs-mb2y7X-W;vcFs9;C0$* z=-IgeXRXZj?NVju{WnfXO?xtW`h=v#l`}$bls>E^hE}f3EwnYv)778&)ov5(%g0!S zhDrDIQ`2{^-j=@R-O1dm__E{&iN}lH7B18`SZ)|_DQ|((jR_;nS1hfr*>y{vHm6tL zQxi`0qrP^FC+l2kiZZpF+qljCVsp*roVn#2j9x4~Bc05cP-k5C)OXV3<9+ps#i`oVkR^D!%uk-W!k;S!D zc+Zj&8}WkQs~$SsljskMuN>tn89C8+t3OtI<;ey~$vwi=BlT~pZl8OqvvO-*mS|D3 z>%0Q5>Std!n#kU~Xh~dSD zVfGVa#cXaEUxwrGLxhnI_{O4>c$|>ufd7W>OY#-F@EI>!%uWH zw2x(hf(X8hjf;&4kCd`v9q(zr+&JC+bB z9f4G|>u}>sxe}pRCKN^DkWMy76eV-OwxTiKL+-v1XYL@+X2ap`aT( zi1GC|6+o!`U){ND=|ZR~X3?#YjJr0)-L$ z02v#Fi%hp+Fc~%!2AM&j(#iCXOf&crDI6oDl}xfGQxp^)m*oLE*^th{2zCgcD2@zK z5YWc6Tt(p`NdOcPz60KdPN%kOQ;__HvHb8LH!vL8u9Z$Ae-uLrBHN57(OF7`9o!;Gphy(%fJd8yLorp@Lu6m5 zl03GIt*(wnAkmRJGLuE7bWsOU5DMZx$Bk+t&R$vVSd&FuMU>hd=P8KoCDVl+LTu+H z_Qd>&rhrgUOyrm8`N-O##aSYY5lO=QBz~Ove6Fl#J(`$1G);rcN-C4Yd4Fb6UHI%F z^1i+-FOU^U;?(R1@E5et+QSnrRNNgnoT7@e*xdG9<0=xM{VYSA+lfLA72%7EN{1Gy zNFa-0OZd(qklGG-XLL#9{8cp+2X86JI67{uFPkfjM1^&nB9l7gV?z1p)OMSd?YphK zFuPfvlpW3QvN&!iJ2He1uL0#%(9@!A1Z*Cc$`BB21zbLXMx*lywl*9pfkqe5ZEd(r zHl5U7NjseGvS?4ZsuYI=H&$7_x?3cZK!U$Efn++1MrKiL@&6CY<1qy^29?7lP)H0m zTogKwx>J zDjg6d7KaP@lFnJKI`!S~smUvfhUl~6>TK=Ot|D<9Tydc?znI7#&1+z6*DzVgg&U(s z+v+UsVNrVp!jju@@VbP@DzW3WsyyScL;p)q){g(B2^{WUBY!Kt|Ay<|aQ&?a{4M5x zv+Lh*{jCW6E#`l->mLi3;m6;*_>u6eje%dY4D=oS;g>Ky&LmGatPTCyQoLg|V0w$a zW=b)vPk+?3u=Ux40I4tY_I1~P(A!`Dlj?XUvLA-^9q;Yt92nGF3)lBP=IPg!0 z-*ih%j9Z_n@pe1Z?vC&kR`*m5uNW$2cERKmoj{8K{6TQ|o`PBJLlg5Dpcg|MqQ;jC zhQq;dlNzpL2>H<)CdfESJ54YekmcZrCpd9couShfC|A+dco+zM+nw>c2U?)7EgL=< zYKjfi#%PH0;VWoI!3GZc4(MB39RGc9oyIwUxJ**n|+J1+jIkaYIR=`uEiU10u z$~X+MUwSr(wz)j)IKhQev3nWn&Y zQ(m>U0JTLaHxoq#BGBpy2oog|b**reOVs9_h7fuiKm>F`emc?U07L=Rl9NjIKCmTT zXbVtnSBL8+#?61JBf5;C)P5F>df-s611`t`dKYGtAU#3fo`^~sM6p}Atwy0C2fC|X zYJ8oBFFVaNPii%z6j&JDEvih{#70y{A_p{u%U_+T>lmC^1vr$v1<+nVdkyU{G&`W3 zfL(1nJrgi3{OuYUw!^^-x-q%O)%z!qr3 zHLQ5ys8>T3A3V9Vyr6=;Q6c`D9*kRp97^8)YVwdbT7$JsjQ@HE$gOGw^`Qfl%OmYK znL7H*$6y>C^HON)#*u;@=z>xm!!$s=M_3Ku2u@rFMJVgP7@jw1!4<4E8w4t$p$Mo0 zsPD{DVC*?xt=W>F(qJLI6WGbf_|3LGynI zpjIkYj`~jUi35n*9tmyaL<+R-P6uNB9DD!~w$D2k*+yCfAYC`+P! zQxw^v)e^EVl_kIPwv;rYdq4O4`u%awz0bVQdA9RB&w0*s&ij4cNK+F%E)Ee62!gl_ z^tH{w6Ai;$Ht@TV`Ri^7T96dDVH4e);D_*{Qk==|Bm_Oci-aKglbs>Rzb5?%*;hg( zBYcD=P!L`ZaX)$IZ_@D=Rj3goWqq~b{HyK9?PMP{^Rpv(7dRw-4IbIjXus_dNp9h? zhE0w)zHlt(-xv^gsmEtan?V1_;FCAO?>}E}ZT!mqVEKrT%hAun@vYr`A^h#FZNqs6 z!(x(eSn7iPIY0V1KS=VH>lS;MPpf-fnDqWxl8F5^+Q^rz-TtqKhCj#5z0WHf=u+ET zVLuq`=iGhqwvc^*+K682#_-P}g;uX~Pjq2QO1IB_+f#S_i{0?e_QKoVY=Q1FL3_)# z*FA3f(zdc7<6&M?al4OBnvGvUP{CbFdTeE)iyux~E9ZSd+5@Y86;Jo@vX1>aHy3K$ z9?UA7|K{uYjgp;V>54R5kW|HjE>f82wHi`WP}{Z4yKm2~yMeDf_NMac`iz{LaeTe6 zWDj#55mt|jHfg-k*pMrj--N=8$B~@H4yha?p{YaPJZ{>5u`hhXX0wjq*%p7|ildzg z%QFQmZ9u~>mN&mW;qkspxTc1IZz+*|PNu#In8g=2s%T-a*jII{lzij6ll~4LbDdnv z!i#Ja6eOw%=OBx&J>T*u*9qlaT%UTC+7#yIRJ3Qo>P;#0j~nXCsvJuyS(e}7^Zps> z<4)~}{pztIhP$11B9@v{gy&jHYzd9fHaL)?AFaM?rTl&V_|&c4Qp*hFQw~}f;0Bjm ztxvFcmRoOQ+f|y7z_(61_n^5=BnEJ|Wo+8#i5jZzyx=Y755A&+1KPzZxz0Szk+q0_;U9&F-q&pqR*|hLVOiNAF zqeBX3Hy=vcB~^c6-w}y=!)u!_xM0#H#h<-8;33iaJl|~a6Rn@~Y6P8YZ&cLw!R;_D|Bbsxn9l}g#a-dPLDUbw9FWaZOq2W)T%Pp?9j)5~0K4{+SA zZOSuj&u)IGp29k?$Fvd2;@bA^aBonFc6;%MryBkqK?jDUjUz;C*)C;Yt@^@TcJ_Mh zU;LGAUNVZjoGU!2Qf!ghNk+zVq8%OXsILg>dT20bu5F@Y--jKyv}1?A)^G0RPrX|t z8W@-PStVPX)5gW%u=Hl>ppbc&L&`%JUoFU6T4!ChJtUQ!FI2jDGna>K2VcNGg_SXi zYz;bQTKDrV;yKLrr9~dXgE7r{uk3l7ZMHZ| zl&M+GTlguVs^b`^3oTby{8(b!^L^aHtcL4@2e}fhF5Kt3?UdzS?(bS{Dt-lZVzB$> za_6LgoUE$Dm-q`M4Z}j%S)Cr)agqBr44vopy{Agor z7lMS6MCb(L1y9M*DBpl-<%wgtk3MfzjZ~>a*M2pCo9V{ zbL{pMENi8u=>)IH3GvZ1^L|=4#{y!%zEP+C{+x)r15A6O_0J5u{fo1c*sr@eHNIBKk9oP{)61CQT`Kjxfnxi@cjkF2dCkM@G* zwlmCYDgqkxW9e-K(|citon`dc%?7$odk*4H`gXoP7SNsH)`5_?M?l;83$o|U-5qhd zdY{|cOD%LQ`@8}L1!tyX{nDMZTQ{u-g%8Pj99%mKUzkTAZA*sXI!IXmJV*luu@vIN*F zX?;KasfIeFPxq)uFh;o-#i)Zzw(^tIKacQ28a&VS6wi7?G@wLoh%F_#P zi;B6$V=eQ(#-M~#^{=4LT`_fksnUL@kp05PV;kH2&z+BCAE=-( zGSc3mOt-OL#CX0~aw|k{kF3?4xBBUmh-2FR159{+=EodD$(N!YH<+9kdTCNFVHauO zC1W0E8@u>s(Sf_qJQTYI4Flq0!ZtZ>!54&cxa4*gp1#M8xU9QEOv#qtT#$?Nh$K$A0JWvLDF_zsn$!!OsR1;(#US#mS^V025Gzw&c*9cwF&{D*rjyHQ~*+=jCT547RohyXqzU!7) z8?*C%SE2!Hz+qo1I!QP)%dH5#h!&Yc8j^W?4+GEQ%A6(%Z*@kt$1?P-EGx=7a?WTR(Da-t`GP7(s`GPA6?Mc z+39gF`hnkLg6UAK;?5k46Oz&GxJ;)$Qk-DbmB%?=XBP-duHSxMJ{?=()btKI7jcZc zXT_6F#du-Kt2!t9h8B?@28wl61a3=LYsr=Pcsh+~#Ap~zyw_pXSnXYY^pl_X4k2~H z-Hm*!YV+K?OD-P}5^)eX`1Z7%6_4nBUrw2G0`s^_YV-~m?6uoq<@zG3CT)wCMPOB^ zLv5TUX?Q@)JUY)e8uzNq$oxjl^`$(oi=e0bx4#aFJNsF4)!c@Q@nXE|g0irur7Qd2 zF=smF?U9f*vEE02rvH3J#HD$xZ_Jp~4bm$&phK;BmWN&2Bo<)2ZIdk-hb;EmcRWZm zYcNhx%jNb)?~U^^oU0u*H=R7Ei&F_N5)X1WLluWAo(kksJ&R8`hg_re&S*!Q1j(?| zHDvGJgUo{OA7?}8KvpB!VRj_Oq{em6x`0g6k4>RVE$uht9Te*jTci*Lw?pcA~8GsW(lAbmLy_?OW&X7e1mS(CzGc@6qPUgR6?I_Lj78 zF5T6kAE;R#sCO`6&Epp?KA%F>2~yO2jriJK>+dykE9UI75zIP%l0e-pcE#=V=Df3Z(A^Zf8Yp4D}n&f8r{3pv7( zJCbZdn~`-1qUT!UFOPCawT7}Fkg{R zptMG0YscoJ14ucGT;a{MZ4pU}3kMfzO8Jt4FGl3lVYN@h@^tcx@8uh)6iP^3pELYb zq@;IUsyHq!gnPF)o%%vADl3Ge-4$3 zkIY(_>G|Af{qyph!6_juI<5ydA%gvP>WYO{ndZa?Ts==**xVjc+}_??@S(k3?dg^L zq^D;})b3wv%r7`xM`mVwyiASziBzgR#|zs*)deNS3vK(KW3Cr2k-T>5L8QK2NubR- zS3gSD^QDHi*h{dzU~nbTbdMc#pPhAR;s7j3N?|_`=LsYl=8jViFhMjGvm8Ullq3=nN9UY1e%GVGB_W06=xw_Xe3a@<+iTHt93#3Yu0x_ytA)LpbIP0uRT5(=00)^|$589>DOqRO3^KtRT1#W>h zTM^!ddyL-Z3_ZK6{-6S%jQOxajq7k1-I~Hx_T++@=K|cZEh@fhyK2_QK0XV!$}y|I zRCQ{k*Y1yK6Dg66t9bjOrEs&Ln#IzHrr3L)nXeih)GX2lONoJ(%5Rped?_ehAY}K+ zw^P^LHe>zvZMSL%yabAb9<=Jn`L`;kMU<+tv40?Cx1MUi)PYh7FeKY3EE zaKzYE0?SUFN`3YGMsM1%|CjC-wI`G-11`5-uRV0{Bl}$k2g}M?+uw+pEmBL) zDpX7UGN@&;y`IDSqb9#j{vP#xXY+#Mwr`J0fAE)t)4GAd09m_h`-|OLEHD^?n32&| zH{{~SBD~LPn{v^&d#oFV&vmOF-uLdP3DPQ+=eC6K5@puYjSbEYX_ot+-Z{7Bt(Ds8 zgB?668mik?8z!6yH)&K|xo~+xx;=+*Z77Yn`s3W&XXdw4PzCT1t=yXzU}mZe~qbti`{*-@%DlvLcKukqf#Li+WG ziYqcQbw_OD=YFd_mAn2<1+uD5jdM@_hH9*YhC;TA=*~~`OZD+y@>FY z+L1>B6*6OXHhsz4z5kM*{PBkE?IjD$IaaW2Lw2nyuKj-PYFT5hali zIP(x)5|yOGZ8tSfAtX@nJ@_@c(c$A2uX~@n+=^|1qUSx@X?&MMV#-Hm%_1FniHi-cs2Y1-@9WMO~(0d}`C2*Cij5x{KbTN()>1D{3Azv&5ui9P-=|riHLM{Ry|< z@3U`zf5#E4V2y1Q>IIc5tOEq`;mP2$*(PHnJdxrdOK_q%l4SioyufEQ2vXJX_aYG8 zNOXiF$%X8xhU~~ML?XyeYRHW^W3;iC7Ri;YA4nxx1e$Ch2D%ZIosb&p9IF0!pumGf zCm{Si+&yV{e>LQ&UOec-XgMTel!fl5hTLRqiqN7^NeHYgRu+xY@hAH#Ak{e#s#GUu zyt%gSxC$^*L%P!GUU)eLMqvtgI}DR*+LrKmiUEEx?mb@JD&lBw!U| zI~$SI)F zN+`4fNV=r#8b|n;3X$7i$paWd1DfT3;)lPoewX;kADHrsAzrQ&I)&y+@nS6Vo&1X+ zo$Nf#JTT=KcHkD{879_c)aTLl!)sHBKCp8J+GfL2y;mUnWTq{6_HMkja@NfRo_Km}Gw8KbD+xEe)NAQ4em9GZku zUQNWIFpkPtB}Zo`tO9{JNyU098SFHI`#-V9T=jG`#N`Mz0uSIdEP%S_aA*mr1aX1X_2g#J|PjcU+4JP&+(~3jOPoY{f zpnlJdG2O-#C!iWLDhQ_l9t039A_3m-z?UC*cqh60z-UWPGB9?``caWhKWJ*m)nJpO z(Q@+e?+Ug!o8&Qa( zQ5rMcX_PotGS?DZdAe#iWaCJR@JpXcoK{9ygAMUzVRqfp(}Q`b9gB@yYr*TabU zyC!pRSkdUz0D~Evn!=|FB5!Pr*9Wo`YQUuVElA#Dqp|R~lSj`E1Y)#`;|avETqBMq zfYaz2f;f*6$qXvOtc%KbEi{TV-H$*eX}W;aRzqsShcv=;qJ|>CT?%9z4zbdhKqPy@ zg;nZjEBstZ@UERUE5}xQ{J@;XJsQE6G{rfhE5Xx+1a1T4N5Su$c6KBvp%sV(6k2h$ z5(+D?sDyG73RBN7d*iL986FUeh_Lj6#Ed6*tJ^@K^;r z4vQRjPgM>+|0fnx6+R)SEVn9rg5nL}GG^i9<>gK$QGZT@iES|r-z53bT}7Eud@|dZ zv=+rH0Gt7?^!0w8znz`|0prK>Rn!AI0~-aQzpqKZ?K~G5?oc|Ap(1BJfAd|7F+zEL2m=$8cytj!veONWb=W`5W8;!m zto6m-fgl8Apsl&Vm6Zv-tmGBb$jAub`e&`XhnWw8M$~~8B><}chyj47hyQ-elACMf zI(YsoZO-4-3XGl)jJ5&t)&SN3U;;3;`TU#4!;}571HkYFz;It6yA=R8tYn&Y3@mQc zG&HEYhsgraRs#oNU4OgHI)%D>I6#Cydw`ij0r1Q)V-W-~>v3}p4=~~b#-jlKA%I%o zfE**9+2Urk0$@S}PE^@r(;Ych6if-^c~P zzYGA}SjQee|MvEdjxU3`jen;6I{J+Rd2pWE0};4_@ct?a-3B-rVDMG|?;%Ky0m}~* z990N{|9BPB`GJMlC-uK~Wl^I6fdAh03b4Tyg518-e(Atvlo51wL-qi^0T^Kb!Cl?+ zM)waRSw=XZ!UGl&p1zh2@wRZ zBo3gDFd(sabx)n*JJ+Z0JqS7kbTCY(UmO682q1V70HgeL2F9NRv{^TxPZ%&?1^{o` zsf~kaTKl2N8yMy~3v{iRs^BLF#!4lW0+<-(eC*4Y(6OlsemCy!VS#fTt~eso@G;y2 z%3JWI-&eR9X4VMnsff*VT4>#Ah z?&+9-o&-R1nM4OgmI(=DT4CIz6&Rs`F(c!PhKHd)H6E_1```&?(HO444>_i7px^gn z41rV{37i;@Isl>%Z?Nf#?STcnvriomvBf|aTm)t?Y{G<*-|YhkMEVopOq}2zf0BUB zqro0ufsu`Xz$p5i5X6!>MR?jF*tBrvx(q;YTBctKbALtsf`QX$a+?oUVKa=FNFnRV z)JgrD++0ILlg2Z2zj*@&>5G=b`WHg1ZP0^zQY!?J8FamG5iIteb1HGJzn0`F00cZl#)2F4tj?bn& z{gr8C4Q%-8UkTqaZQpw{cmD3ZepXj{F#Q__CMdxU$S@#Gp!z2|vv@Kp0<#c+K4b^!i*FkR!Gj=%t)&j2?Q zDi>6_!I_xG=pzdm@WGoH0yTBowsKm^6aqKb^|t^8A7FpdqW*vxzST}`9IykwYkyGF z^?{zz`wyed#%PX1;C^+R5n&n}!(hS=OulDKmDOu&pZ>x=l^GoSEdYlHaAPWM${3ui zb3CWuW*RCnVCaV(_{e}Tff8k9g%l?Svw4E3e&paV(*eBj;g}2n-lT9fgI6XEfO=gW zMCRri90vVaweh#MbqttWn817IB|tD`K%77w2SyPm27l)X8!+9MirMG`7esZycZ&gU zKD+`mowjyBffxhfS)=}m@l0dyoYSRSIqbm087zU1`pD{<+3$rJ^!*VTWC$7v!2feG zqxJx#5EJ-PHqs8Lurt4F#vqlle#h{?ruFm+f;Yz2yFf2o7#K7rA!blHx&Wns0d*?s zG)N`HROG)m{sg{PwZd;>(-;rkg{$5~)Kh0+2>2=u<$x>U30B$w=*$2xcN*Q`>|$C1R-kiq1waR` z)A7?VPen@u#A7gt@>Ie<9mAhufL;pFlL=rtRV)j{qu z-RbQeX%`V5`9;OYW+sS(1A=dsYXDdQfQ_E*TUiNU#ZA73{Nw;o1m~bQc$5N|Z7RWH zj2fJd9{{`u0N;Dy0}(L}BH;O_4Ne^_h<^2C!CxGJiNFah@VE{Dp7j5R1}~*4F#hUP zW4`Z!$ppX%A8aH5zvjSX#{auMxV`>rJUl%^2Vep>SMDkBAOM)LYcPgE69Cf$?GK)}0WY{= zGNk~+r~NNBzti`(9hj^XIKu~=Q3E(-0ILANucM0qfE({<`wV_R0)P*>asUs3(YOCJ d+Cc7?W?%W&T)A7X;5!v$pktz)vDP8<{{bxVEkghR literal 0 HcmV?d00001 diff --git a/dist/icons/icon-501x501.png b/dist/icons/icon-501x501.png new file mode 100644 index 0000000000000000000000000000000000000000..cfada56b328cf74868ce471d0427171340741397 GIT binary patch literal 1017633 zcmeF42VhOtAIB3THbL$6jF^o)BX;E3R1tfWdJ#daM8pc^S+xnJ1Lc`Ds$#Zic~Pn; zf)-7Ur~WltV%Dtx@5Bu+k@3de_j}vxy?5_9zwtTach9-!-pmMS+ag!?qS@Wt+;X*Q z*|dY3oBKnyXZ4^XcUtz(>*iK?d1R+<5gh_Y>B7Q8`-Kb+)t3NL0|LDW*J1ea}P$s74(Q?<1Pk6cS z)_=1$-)uc%*Y*!vY+AOt!M*99gzlcO@8VhO{rfNPk2rd5PyDTCx1SZ7fA+wj$O-LF zJS$rM&S#}c4R~_@zo!pBI{WBZo4=Rm|7iT(5&KtHX|Z?9i8B5b-n;ve|G4oZ%kI7O z%hS{UjQelRqosd7vtF8Te2%f(5Xdzrau1YugCXi zew^pGm(L$|e13b!_&a0n4DEMw!2h1^TEF>&F?+9An$@{9pwoXf|0}RJ^u+R*<+s1O zl~OO6`n!wS6G?bwIkb-Q+?V4dn7ZJW=X@Z!q&30GeJd%~x}?ykWlC*8TU zrBAQ+4-ZyfSog(=_T|c*Z}dtc@Fz$f1k!>GVbkgZiUCCK7&hp9%?(je3f~X4mI;=Jj|=;#@TgG zX7hfuZqWTN3N8x@nsMh3OO6>8*RO3pa6pL#i-sRwH2&7Y*a)vhJ>OfuX3>YuzwrI7 zXX{NnI$!>E@cO^H^cb?~VXe5o*I)ZE@}EurHhfxqSUKa@-?eX1?4#M$Dir#1O!zm4 z?|xFdOV5zMI(O+clxJLKd7clYBPd~eknyezEZnoru*eYpMf zi8}W?461!$+|fle#*O*r1;abNF-GfoZrr^T7kdvE)th_V&$i`!{Fi%5eerDG znBh(Ty>!+4Kkwmf*FW3$^U{tt#~(Sre9W`fX9hP6Te2+E`W!PVW&L7+f9}Ow?iZ@} zWZvc)vxg7t={?(hlkewqf`46nXXziuPA{CSzf-(Io=v)Q=ORAy+2*;e<7`8=&VO9o zSZu`i11paVzrCm6wgrEbYyQ#kg134;j2L?4(dF`$zTEcS^09Y<2F>2P-+PPK{xM}^ z{D$3G8oI3Jpo(9$sXY6GS%tptwdc|3e*eshc3V;VYFz)Vt-t?v#~=4vEqnjsmrwo5 zJ$W$ZMfV*&{7(-J>r!<3QTG)QIqLr8>mEOBVD;=}dPPlKG^M9^a2JpBo5QSKD?iUR zqGXG4JFf5OH0XaXf7o#8!tB@`ox8ca4_p&IYU3}1Yq#At_G#RiO5RUPm)Pp}c))}6 zO9s7&TmRXH_upN&y~gY%lPb@y=Qp`t<%mYUlSV)K#1djD>GeyTcgFq|F17r(!q(A+ z8nxY?E!*+0BZp2LdA&f@4;Bt-Q@rEVBilY(-N2*l;NXwPtvuMQa`>jLm><;o_x{JX zcB^{h{ZYG4pV?7o+K?Izm)tS$nicxx!)F;xJug-480+6Li^sfLxBu!{rQEOc)^-^< zrbYIxp82XCewh8sVmCH+o3?*<)}J=?t5xu;W8apFnzDaI*2Z4_GvDo$)iS@<4h}hN0y!UkAs4nZ)jL4qv*RrwS=kXl+&4^qPdn;Uz{PpOc$EueK`=HQ= zrJg*g^;?dg3V3$==SI83xj)Laa^lTQOUksVR?%?iar}^nIo*QWd)CN2)T2w`cFlY` zM^w4IbZJ1o;kiedV(ZPQ(IDTE2M2t7Z-zgrcI(LU*bH4J95m)@J#gbOlkqEawnLX9 zr!4R0p80UT$15w=%hl{g@3}p#=L>(8Yx5t)<}UH>{=|I4^5CO7g{^V-JB(j{=f_E> zzgYQh)g8Oq?EbUEi6**?@2?#-W9X2=`TK6IXW97CxVT<-;{cgeST z+61@rjSbt-y>`&bU4QJ^`}>O=lT6h@8Vqb#JzLRomCGK>oYga5mzI-b&i!vuhd=LU z%iE|-_aQ4<4$jxM@4u$M?i?PJJ5#Q3_k|Vy99!V&>UT5c?(gyW*u#0g?{)9w+S5N| z@S9q5OI)`3?T>!_aO2?1{R(_@^HIlRt*fsZIy&!yqDw1&TVmt3tUcC^uj`q&L&ck; zkBnVkbR_Jf0ummFUIdHAq>HwSv2Sd{+6UW!G^}yY(zFU_h7eb~N)| z{m?WZ&#Cr(qq=PBbZ}a?J1x)Mno+X#h*h0*U1mn^Z=^r9^7i^QaTmH(tlPHM`@VjK zynf2{aCe_7Q_lD3IlWW9U$(~F|M|sC)AUQf=9~4h?>YCN8!z1NJ$q7M=(Hm@zG``K zM3vZrGd5hV*ioOWMcCQ)wZH8W;gyMgs z7cc)jHrSl=>&2cqCJvl7rBmP+Uwc*#v4-6t1l^y9*b-B!#f99!k_*l7o14~@>~_MLV3qD)P4 zUYh)AqxXH=o{X81r)=hG`7X_IUp@H5M5-pxCE zdOgj(q1@3d-US*B2^*g)+l5@`f+BBZ`>gS%8$YgnQt5ww{(XL`bu5oxk#h5{P5(SP zpLlmK)igk8C^2c<@{6t<4eBTTZ#xzSoRz#&@Y5(sBIB_^ws@6mLCz z>d#%9{Mg95)kiO<=V|zbr>@oVp4mP()ei_5P%Z3=+3nga&t;W$)xV!rc+I^=^L4}B z2G05~y8Euq-b>0q@o*pLH(_|rNB^wRA3yuxW?a|HqgFTjeBC!Uvy}YxyS#?K>V95p z$W^buO>K_1s8C_H+u~tszx^@y!a1QY21ZU=bi}fM=*0{xE^Ny(wr1UN z#j}r|x9rU4=HmZ5`0-Oii9QPhs&shwN}Q>7?<$e|_YWNX&79dG%V+Jl(C1~wBO81C zkT+;(MN^(bneyd2w)jGZ|J6D^F@ELK{9f1Zy!+cHKZb`C{9mP~`6gx$HqMOAxclsd z_Fpa?_}Av}5&EOg+ecrT`a!|Wvu&WNiRs|8weQ9DMTU>K>3+Oj>}PAw)#<)J!>R+h zG9Abr*}^%muKc5E@X()r-%om0xyzt_9swmHE~zA0O9^2co! zMSS1Mtxv}*pEl`rG^B>Eciqa1GB%o2B%s3M{rP81Z#dYv;mNOF9hz=AHg{&!!iFOU z{QRWvS^p7+;V-J)Y&E|}=>Dh~@xPiTo8ki>XKMM~;u#eiKHf2CXqJZocl*rCGBj_X z`&6&i*?(&p^kx5h=9`8)|E)QHx%-~nd5_E)T{`cnCQb78nR?~pb2SHl_xZmCziU@# zU9V$3tp_H}{Q7$J8ArZ-UOu4M_^vG$-yh;udDPa7GXtws{o%-kpR0GYPA~Rl)cyrW zu72z8e=~cX9ulmWxZ9fpT{1znJa$CH*UULgELdR?!Rfi_34O<^Z#u; zx^9sclg=)ipVQlrxpceVx)}=<@1U=eqpbVyS3C-J&8VxR&;D12=kInab#BDF#hb2- z`TdkRXhMX(&E}(zzCL;{B-o?ZT*KIPnB339D?dKH>fZDZdc2eEO#ba2<8S=A zu-)og)v|xRcHN+p?_4>&ruDtYWe1h()B9juw+sG1=rc@RSJqs8s_DAtlFL0>*IvHL z{l8+9{#loEVQt+UuS~1G&W$s)xmWV1<+pX63vD{wz3Ie-Ri?Mj{6Uk0C+qcX)4E&z zIsYAc(R)W7bEe%Zw|v)d?b!FOe>@_5+QC*un$KTSEZ3gB2Y39jxL>7;^@eUMF*H;2 zxYBH1EpoIa=AC~g*Etr3Kh5mJl&v`WX;a>fPkzr9= zOI5tS`bmxhGyDw`@_lipcd4hjeYONnw4AzgYVNA8>({(vdQfZFf4^^8Hrqe?-AZ-V z6*qjkzi6AS%jV|!Zc3*XkA_XC>0Z0auzlN?POS2ImbO*fo>?|`QjfBQSNdfhtgl?; zy>)ZCxEqd^-juQ1rLx6`R%tzO@^8(pAv6AKneD;+e^!05Cgk>|evNwV8@8|Hi|WN* z_6@4p>3ZWiy*)<$w`cZ+Q6&nw%`>~L?|P+lx!M<+cJwShp{(`Niu2>X9?zkYK6Yen*ZqLELmrJc=rFnFmLwJDa%V$+5T7lX1{*l^Sjk$?|Qtfm~GXN?@vX3 zk}>A1kJofuyC7)Sg_Gm0HAg;dziP4D=MUN+Y}~tj`!iYp$St)-Stm&b%tq__5Kywm-Uh%A}4b&Tbo5 zW%2HnMdIVnEpNE<(XhBx@6PS1tJro^`HPiHmB?DS!dIp1y$HAzH(~arGKcpU$yD^0 zHlJSpJ+5l6Z@wt$-s)GcxXnY_jhj*5uX&?Bt1C^3$T>LX^HPHDVc-0v1@Q#lPmaggh>CcaRvo;*y zQM6|Np394ziZYzJxODf^w*OooJf>UqDEB4(%k0|{cK$?(xZINiGadVUQPcj#qRkV7 zhWr-Lr+wxp9{&yax2H$W`qSNyJ{aS@Hm`^8xm?3C45;;M*~(tC{*7MU>cf2B&;RSu z(yYFJJg@V$=MAsPKNaZu$0Lu(kZr9CZFunR=UH#`vo`-=R)Bj{iBn^mPAT{8h|mA( zG;i0Vito%W{7vWlrHVWmv3>sZ4n>EYZHw)2o4j z?$&D6vv*k9F8hS6@AsK^*rVc%!rOCR`ZUYK5~dD6e_!&Exk&W_Ssn~NQ}F1@?)ux+ z$No9#i<-55$iHjF(k??*#oj#{wrx-SO6@mH?_Jz)PsR_tzpK!! z7aZ>~V|J;7&ubOWmidWqpReQgTH6krP;}pvJr%P~ADN|g+d+MP@hda3WR?o2w&tzT z{y+wwW9xHHo%y)s>MVN>ZQghN>eZ|EOND0dbT1jc<@bxZ zn$C+a7Ik)g%R{@Lm-uT(rxC}at>cf+dbjcQ1)l#*7&c><{y>R6bKKgWFs|BOYUQEQ z@nJud`K9Kw=K=FepWit-W=FRA*6rC={xc=gE#P6{iI+N#trgj)g0*T*bLD) zefp~Rb}nd{`A8Gro>vxq^kbK0UqxjcapGl>Lp_6ovJ@;jqEyL!{rUu)TjzHoGVuJa zMIU~)Y}z^V;i$XTjveP!(#;I%RGnz7R1pYCng)Va#mgVo<}abiJ( zg&wAi{|p&YZB-G|qVRg}PQP>3+f;9C(-z#zUcP$W z@|bF3?5lF zEkBfLXOl-KKG@K9<+SShPshD8AohN>(9;k8TQ#uD$7f=S9ILUc{KR6L&zJUInQQin zUWLwVYVLku_}`JwOW(WEzvjjnpI_a$q34{b!*chE8usAtN#*OF-+cNzH+|!y(|h->G<-nc4973TEZy<)ad-bd(`T>t%kzou>zx%B zjJMqMn^k_@-Sg+KT&ugF|I?*Qn}2dbw|3Q9%eKw~eqL9hs=imppg#@;T-WC+U%yAu z>#OQLZS`>JooTI>esnBie2;tgiyu0&Y5mq46CM=F+I89Z=355(H+lAaGu}oT$HtR&IN6MEO9<+Wb?pp>(3hW!PDUt zjvX(!ICI@$JDPm`;^f*n^?TG0%DJoS_eG9}v>duWD&O)(UwvG}+^TldIS*HryW;QX z`S9AHF(sd5GxptEac9fDgWV4|TD!VxnK70#%WBRwJ=wGD{=|}7yKNdgcYn~mDq(|~ zFKCc)klVIrH%_%|)^1nJt^4!+>icx`Esq^uF}X@+D>KBL^Lne_*PPHDUteP2jI|54 zk6Qirl8*-*9JKNI{b))X3RsYr*{=Hx9y9|DdM~v(I%)BN%|G*9b@0^_C zUZ%?c_rHyqt-t%X`*`9f(bJbTzZutM=cw3mH5c^05LGAFm0VSS?b&AFyEzKhEc8>o zmT?~O(>Ca)>rY2CDb{GfhVg%m^<7%reciyZUEb-_yh~)&yF>l_SJhro{%XcPr*{5O zKJRz8&tHhG<j}FP^=@kuQx$Y8JeDZd10FO?B7v zR<9j9_wb-~Q5S#E<>}{FzH+IVJM-K)TH#{%JPSuwZMbt}n{CTF57y__%`7*vW`}Vl z-KsDA_C%d)A3ZddkI(YS9CQD;1vzs^bSu=T?uod*hr1VhVTt>C-qr0TY7VOLPtNxm z4)iZ zmVPwfujP-1;s<+o+)>#(_ejrSKL^zB?pa{i!pa3>8i!Qbe$yC!V_NL$(yfLKd#7iP z+~eQvQljV55hKD1WQxh-S*UA;W`!!%(F;%7E|pqo;$>5MNTt8a^%dhPM$AhQdFW7%ahoDVk?-laM5f}dPt(q;OEM*q7Y&2zd(OLl$rxxB+ zv{Ly~+e`f$pQrwR@9gRuKEyOXsAT7LQN{fqmwJBt%)4#de%C6dPV9?5f0SBfFcunc zX2`Q==XNfsV0u~PyHj!h4b1rYlX5>?JX5BH#ZoJ5*o8Cy^RtF$DI9sqt4Vk{|28YS zWx9Cc`jUGVt9R_an~%=K9lDV*YRxyF4mC|~qU*8pZ{K;N{vG+~(VZ{4Ozp{yx>})~)NKukKU5x;Lfp9zJGhMBr%e zp~K5E5wB!44IUm89ugK25;|1JWCr#L9TDMIrVO3eal+|rP_xl=kW;{ZCx{;&(buOH z{isR)Py(OodVL*leRc2Zb$x8})7ds{UgsV)p(DbBf}4#D9vV^BR%zJa5yNeDju;-y4kg$y94e|*d96W>!8BUU`B}vcjG``M}#2Sm=S~dFVs|DMLXcrzr zEiG`cOV+S*uGc7_m0y|aRrLwN6OIH74vgp*8a{-YZ^+QTp`(VsIn^m-NN~r9K!&TD zZ>`$2Rj*U0mT&diwX3~J)Fn84I5i_CwVJ+awdx6H`Ucf&PBH_jI)@Ai>>unCHne}j z30Cm+nuHDx4ev;uNU&d-TE4zDeBYc32pJtbxLZ?FJoJ@RU;Qgx2^ka4c2D8#>$>qu zcAL~~bt*=(gTVKOlU#C-beLa26dev%G(fiip1inrk8r~^1 zbg*9;RyaDwG(jIb-G+L}zJU>ew&H4f>wTHHYIW;XtDa08Q3&ZbCcV_GPt-Nwdb@h> zhXy53dS!Uugp;qj%*KKJeO{&YNh|SNk~$6u9W~TGId77_meMFZVpM4OpmyQy`V0&X zibz{dN{L@f>OjG2ctrS^R_QpEEL{U4-=_$)ya?)dIY;WmDf^+hxUsY6&N1es6SP0zcP(jkk$nx_Mtku zmZBQxtE<>1Feqdw>sTu#wPMtOVAg6=t(C7zn+uq!xHmj-WNo_7TY;Z_$ zc+zT+*ep^>XOlmnRfVRT-8R{)+)YBm#!w6x5YcYb&@|Pjknoj+_d|lHOHEU^ZIV}5 zY%Y_?7c|RzQ6@s4iRuDF=`iZIYhvr#Hd}o z;mZDILMV7BUH6Tm>7EW-TGpbeB9A_;TQqfh$^J9{@YN@DBwJX^?!(>Oa^z>byW8TW zh3R0Hh*oWyWx0~gBUh#3?^?e(D-Cw?ZNvW`b00_vLz`gtK zo@AdsnTfw=?NgHOJ4@CK%)dGP_rP-g0*eHPCUk_uZsg`@=E% zp~6;@s|e&Sl@?p|ZgfckGJ^mJD3Sn1>WVBj^%_mVoQ*CMcib;`yr|i#cl;q2$GIT~ z2&jSpM(V04MrAuefm}x(gwf7|d5Uj%t267~1|_crAiu=kSa8Q5brG97^nrk!2zX76 zi$s){Q;BHI7K-jha+&Q~dG#B)D(Hs4<{~Iw2nPZA6F^Xxe;KLDLT;FDBB$6e9rNw{ zl`j683x6yj2?P{N05{ncTXf1Y9HVkU%L{+aMNqsD4g$&{fS|6NvQnI-+^F10hO-;! zS{RiV>N8}dlxqR-mt7RsN?C=Adchgxi*71s-Oh~ zKtKru5Y&}WN(!-&f;qcq&Vo4>!3kexZ0S4xnv3w9p#cOGMF2rvQN<-sW4U|hCbBNY zXVv6swc@S9UvuHH2&oQxk~kyn?7}p0i={77^x8ga;sJbufZPe-{<_>tNT&92ogf>P z8)-){7q^_)Uvn|LsIuXWF&{~}7QjXGg~?9!+CY-cw5L|5`Cw1tv4Mc_1Q6hbXRIm> zHi4Z5cP%W6lUw<*zvjZ&W8;AU)n_A#S#F0Y1a>~K(8uQQk~Y5 zWA=>D6a8oPJ|OW2K0!dP1Ta#UYspA#7YpWO0-NS#I|8}1<)QUaV$+L1O&4S>0M&CH z6>Ti-j@EI^nh-Q>@+N>)@$xPoNvxwzj|FuT?T&VOlGv+qr7XDPuetD4$lQf%G>LPj zZtHn617bixFaikbf}vHOVCwLUWVMO*)K&!3DQqGWz#nqq7kCtj^Knun+J%$gkWD-S z2xOna|BY_2y3^B!PhZ2;ly@{K`Z$i>Q;+ zkuo#w{pIOSZ zi0ZzcEN2(C*g!y21Tbn>VR3UEnweblQK5TkbZI^XbXH#2cpyOa-;>0cY3JphIu9m6 z1PF*m03&tLPz$e!b!N1)(a8zg5zvK4&W8r}UeYi=1VP4Y0;~<7{=de7FIpmik-ADs zn}WH4TrtyLigs+uAi!3=8orE^f^vA8kP>$dIcD0to7gD5j)FVsxIAhfIF4 zAZ|(AX#~y!IyUhLm`N4xsf))Onq*1(kP2uMRU@#pSq|4}nMrIro<&1k$^;O|Q|2PqqipsBYfL049d4izPcv6$3DiSnIt1(w>i?@d zX`6i30;J=XdQMXVGLSc{1H*_!*kWb(%gwZ7nq64Vyh^9`5k&(1c@+v_ju2ooCiA#{ zDvSbsyd#;BR#*b|2Y6xafOL)kH53zl#Udc#YQ$XL!xA1jJA!4wQ=8vzFVkl*s$Gfa~xkKB7mSS5qMj*TxVsWW0-Td1>^en z#G!c+DO8R6-EIs9gxEcF3fP?@7tnv?9Avg^eEqY`UF|(4+Yg2PtwOKyAfLcKFD_7TAz3 z0ai{dum?~(w4|FF33w-Z|YSf9asXzpDewfNa3bhp@ z8G?2qi_);$2sZ1ukIF90?i@(S8v*y1FJJN|41&@pKo#9UsaW8_bbI=^(o4aDxrqX~ zHNAv5uRH?OR`g``37J{m9v6-Ye@fEcz`@!my9E|6vvO3eIT)#nShU=zV;`wZ2 zkZ3JH3>8r$x_8bVm$3>|To5ZW0@QvCWYRpDnFVuFCcxULvm1NCyxG~z$d@(&1o*W1 zICYjPtdTNWXlGZc*z6~8nUV%lAZL%PS?te-lu9Q+ZAM2vL@V77*l#xh_5vF$rn4KD z{Rt7&?Pq0IN-m(Y#c>Geb`eWR#9sM2k#;==b92HG{G%BH)Mh-%Sr*XIW;9dk368Q` zlnCrRmpOtuk3gw&GLtwK(6QN1fZao9!JIvZ9&dj(q*M`sDDuTeMgG7Q`w6geXK$v{ z+n)s~(;|SNo)#Sk&T#=9i+${8#-`c@xo@5?$M*XYtp%{(d!&4e0JWhoI*2y(78y+) zC`I0~(K~`X55?f#h7=;n95vg8N<028+oh)pdsP5yW2rXq}E8~VyL}$y~W3}Wse0`e$*LKWw zhV|swKp;5*_Mp2l`9b`)k3c5-k|C8X0R(hg8tHy#Lv$krb8EUOwUuDtHorfy7U0#8 z9T&#hs{4+5%YwWc^&w_QGip6OM(qyP0IFzg9+8ba(J7_RE^(x8O+P78Xn_E=9~1f6 zP7A)mN0$j;^zH;g1a$|XaRJ>zS=jPTY^f7CNvGJ&^r+O6;EdJ?Q2Q~G&l9xfw@UrB zh~yUnyMv$+)a?Xj6VP!_Fl}b@DVVc|(s3U>ZBCjx%e5a|mL3IpSqngI$&(z9rX3f@N~!_!vULL0BeT3r zlBYEY@adEbf_plEUY%x(k)g=)@J&p22 zKu-hCn^O}hn6pRN;@=#?HxPJ5fE!(@X@RK@Wh*HGHexqQYJtp^yT5$-QsyQ~V;%x} zy4=~+JNp}|mUL4hfhGxXo$qqBIZt)oU2Q%&;}4aul);1j*+;W8cB?%Pf_e%iOqG@0 z1B|5|Q-&$dfzP`Kc3p~DF7$=Gl|S5T+MR=s2DJ!L+cKT2&#M-ZYl4*~#$Ccsw98--S)H2DbX zHYH{g(A9K5(8fcTzp^W1qsvktK(z$8HpButR=umXlx5`@0(-LJKv3s^AfP9!8A*S# zd+F>YGv=g+@e2grB4DN?xF~)L3l0cKfCYBFfbtb38bSR{ak0?_I-@r{62Gx~>3GRZ zA`N_|N`N}nC_33L)dV<^oWMKBtG5zuEkJVRJpX2oxXNY2-+JXr0s)>tP{(AZ4}Xpc zKHd;ujg~Exv%WcmZy@kC0ct}=IvV=+85{utQ3&KAEePxcLGwYK3+TN?sdmaz!WPG2 z<-4-VOcHCU4Y6rZHe$yH0#XuSfjye)qo=EsxOzi8p=>VTk>v_p?I;c}eq@&V{R&@zF<{SdL zW4w@>2v9pR(nly@ye43H{S9A~MnFcZ<8MDGx+cxF04}ptZGfjv$&=`?;GV~2O6m}R z;I58x6x9oAM|x6-cRh$o9m)hIz*fo|1lA#$c-01VA{s?In|i_K=7xZdTHr7N?!wsO za7JVR0r?YPFO%2F-%Q6XRAo@7!U`i4SS0tRKCl57Zy=C10h@r1nXa@^Y5A;@ z`xI8Mqt#e=stfAW85yXc=Bcr;ob-vk5?0BL&q=qD%|!xHlpix)E<#jucIsE+74Dx8 z#S62-eR#`!VS;+Ot;4SiyB6RrN0J}lMjEQT5=-u@oxkzEcRN8L*&71Xj>6~{X1(4Z z!8i31U<>MuYI0AQ052UO7SJ(u_=^8TyzgDQil|i0)WHRi?U?maY5~G-X9%e3O?0XW z>eLyTs5JeZDNz;XSwR7v@xTTGb`zjBq^HDYyEAAvA>)KiJp|Z5&`kB;Qw=VuBB)bg z7^pBNsG&f3@F9i*x{(Jt5TPLgT!&^Rmod|oez~in^H1MRyHdp1l}i4Je8|Ko`I~8n zgu(HX4SP|B z8a8&rU8iJ66dlwFei*@Tr{n_Q(e?mpV6i;PgD4FUpf+SAH$yexDqIwZfXV_p8z4pt zgh~{#iVf=28R?18JW(jgU&%0PSQh!42@B;!fNMj`RyKw(s-^>10t9&R_i zbyOh-6dTluuUR3Cc`>s`y-%*#u@-5Z?&>L2i8X|0o7o~2c27N?XSookast$b%;X|2ik&ZKuuFp- z^+`rLt%m2|N|7II0I8@=Q9+$LBX)&sRup03jAg6dt-^_iWHl0?He@8fdaKbl_#`U= z0c6c(Sy|+qG3=2y=8IxBMFn-DYNDN8J!yTLPXRqzt`K6&?<-=*S^&A4uL--TqtcV3 zSTLuF(w5dqZZ?qxMm0PFr>H4;#RPcjkPK8oFa=L9fS?8wCT)|2cBK)Z_Tx!5Ta;!u z>{TuS>ZfAKdNuS_dB_j5Qc6M*L7nT66a!Vj!cVxTE}(pfRxbeyxyCvtY#<;S0SfG9 zQZ`>Sg~BOnM{y`XIPv^RRzy%IcTKco3f|2P_tg2T`L5l(@Vc`)&ZV6Bv10p?6i04$;eihhN;ILcp?S??&27WYW1datVOu@gJf{&MTMS^YeB0wFFjx36nmsPMv%LKSt zM>X7Qm-UpqY=b&=N_uJl6SUk2IN#Z0Z5D6<0ecBh+wr8dETChNoW0PHP80&vmxYlc zrQd6315M_KEH~K(b)pp|OJd?0#ird&;;Mu;xe~ZDDr%||YXMk0!h$)u7AovA5(1^) zYiI9|*UPdfy{5)R$}-9mF?LzxFH36T8ihZqE-r7yYvbBZZ^b(T2UJUdhVQZDoJj=^ zvMXrWZL$mM++3nbcBI5N2=nmbGgq`mYC8sUV4k9#fbp6jK!KeF#4QSU)}Pv(QEooS zE~pbAR@hp4(zi;-k2MsI6a;ewS5H=SCWs zI;2$@bR`=vY0ZFg#Sq{+6&BFta4}rqVb(=XtOZaE?vxDGr*sg<>?gqWcSiej$TB5s ze zOHs-us1p<;LD720#HOXfgkvLit4#z02RlbvBO2m~A;ppt2L*({)wMNp^mXQK^vZ$iu4 zWvbjJEdzk>_7k9huA|h^_UAy#6bMxGKQ>frYXMTgAg@E*lzfc5ta8{I6E|3OI3u4K zBoFXhM>T;@rxYs7s8G9Mw#Wpyj)MhvtzQ(2Odje4CSWA_N}iH0MfS77s-&CbL7lue zNlHK-%46tC)glj5V1)t*n8`-1uSHQnF~LMf2v8qrrSwsbxE3HRJuosq&;F*XPAVHE z3-DZLiA)XCu} zshpOPUiN5Pyo~IDDKaEL0o{|#GSiMlaxyF*m?Q{+Fp{d|1$6AuH-jK#(h(|2P$y@N zWEWdCsO61SSX|g>xdzzpyP1+=k(~X!kW%3UxWSIn`$v-$#UM#gCr2f5Rtmsr=)^nV z(}06huL#fuu!+85ksK<7k_dcsF>g&?*8)(GXYGLfF)XESl8oF%5AYbVC)7{&G8(f| zYbxv(hXA#e0Mdj7bK>BJ7I_k2Q}RmQ#GiTani>}=dSs^}GAX&3c(NS~cmkbz84^$MYO;z{0_ zX~#-A^%gTcv!8&;{-m-@DXRUV1$C~Y64g0b7B6NhWLhk;GRsWXV5OX_iUh_;MSw=@ z7Sg?ifBmZ$^eV{fS^#@YEG6d1U963ciogSu!=i3QIIJ!U8JAd5x_a98tKDW{C`*7_|)QA>$N?p9K$wn3DjPHdE37aXS@RJgoz>(po?C1 zvF9(cTBrj7MG{cK$X)PP&0h7Z05!8M` zgF1m1)OdvyYz$pp#wx^Cm?;tg3g~)L#YXAaKmY_BAfS@by3PTY9ZD)#Q0GSJ=}#+` zeD={Vj;{r9$VnL`Hp|Esm?8rL)J{CfjA+`iU`__*0TUESz@$j4-xw{J{elH}vfcQ` ze$9TvOK3D(^l3WI0y=I{rHKe9K_GPk+{j&kH_@f8ljk$N>Ed3;v&;l>f&_KW*xo`I ztT35oh1m;p1tvgkgH6AuKbs}69T4w20dB^{bwQBeECJS*l)M>*FkX%NvxQl+*CD};eJ;0Of z0NSw_2!A`O^u5bBC_*usc4XS zQ*@VVTr_XeAV}#1EaU*Lc9mX=uwSkO%yKo%4!c}<$85^dc@63`EHRK8pOjT;>Zn;$ z-on{b2~eA0bpdT6RYEuc0xlDXa#@130*rjB=QXI4VZ0j0r=udvGK;J)iMk%2UM}O@ zT7V>C@PkJJ+zm85BEln6hysD+1Zajdo{lN`Z@IE(-#nB15?H?bG(3ST<8j48#3K?;{~lCBu73im-&^CuU5=e}Ck0#Lg!6HF|a6SYP` z83-g0Q2O9XJ^`L^8d0ed2$;b^y96kp8_9dDG0{#HFlfhB`Fo1RbFa$C0t4_!yztXP|Wr9(@W*q$c zn4cYM0a!i2MXr2{5teC-fRg)V_7*z5E5+qffG6cTQtt1H0V>L?~uVWx_$K|y;PR;65zZl37E+%OuMVHXyKH?2`G8yl>P120B89-9n?vwo|Kky zR|+3FEsQI9L| zBs~HY+&w9cDZO+!4+0<{4FMHQ#|LozjKct(9<`Gur>`U&wo=|1Vz`$f$lFR-$0va( z5{4;wK8ZpW2=GrJntzd^No4(tb1~LyYFwmKksWjKNlMp}(13B1R)lR}W zdkN_6O^9@o5HL%kl|Q9UMRuoxI@xUG&u+y_Qt~CC;^9l+fJp+KYE}8p9M4^9SqtE) z)uM}q_@q_>N*{nZ z9BUm8>X?R4Qui%Me&L7O2}G&gLHGv(DkES~xIe-Nbpm8mI3zyJx9}+pvgAvEE@q8n z9iH!$ZxO*V5O|9K&7>-Qq~7i=r_wp#@JOBHIeg`ijtxpa9jj#HVY@>FOb(?+Vzm*7 znSRSxEo%YPRyL0Kv&E6ba!bqI0<_yKhXOpN;gfQuD?&@sBlx980vNHYu~gxch6q>` z?yEzCYKMY4fiWl?4xi@7@F@(kWKF;%YwKVf2!KFZ1T1NtRKPhwgSt@x0K_s8)9_-E zmQW8j^@aQD5|#l}gMcdpRPdM^duhDhUIuoL)Jdo(3H7m8um;juG~gp#baM*>1Q1Xd zfv+okx*KZ&QZF=1>ZcTO#%QmVb_aM87+|kZjiig!h@YBule<#J^Xi(d0qHufOE(1) z$c2DKE`~U1hr!-_2;F9M1W>IA}&7K}85 zdU~1D60G8LRu%iEY1eQOtLfr*)_Hcj2Ae_%XkqnS2Dd|5zMNs-S^$GW%1ul&tzs&J zE>Q^th^h_BKmY`!AmHR8Iw?#|QD>U>*fDBPky+{ox%U#Lo&aZ*Ou(RI<6%1pfPh^D ztahc6aiX;Dv8NZ*@$h=mf>ruUhLd`OU&#p=k{`ft5C8$y5wNPjBSUIFq#D%Ix)MlD zm$WMLm<^gq8t}sDF}c- zdIVImMvA>KKE*yOt)QM_hV+2pJP0V1fI*>l!)y=$0mlib;g#Si#^@A-I$Z(ih!Oq( z_1hK2^7bJdQ3(N^O8kHuAOHgC6NpbgiR@F@AJoZ}6cfwdML8K*ZqoBD@>vTYCo)Q~ z1&imDP)e{71o$Cf;YW<5Qc{fBDURC7%oGz#YCe>MfItNB1c*RjwISA^4L9MX3<;$8 za+=hFIx1=kB}j`cEGZnuA>|YBRK5%F00cn50Rk2W(#kezN(<*w3+foD%eEL{m;eM& z-vxjQksts9f)jYV@A8@&7x`9X$ErEOOF~u(eyV%qXRHN~Rgu6L5C8!Y38-iq_N^%Y zR)8n2ZzU3uwVYMmm9ufM%_RZ`mvSRB2!H?xNJHSQc#WWLe?i3BpA;!U00ck)1Y}M? z4S)0lL0#sR4Ca9V2!H?xh(o|Cjv7I=u-DG%Y&E1bQcse=HZi_~fRqFtw27S~!dig0 zu6(8R8M+lk0JC|DDlSzTtF!egr2vn=(P~Qw-?cyhuUXVWDGTFcyf9)RRRjWRxgayx zvPu%vQ+goIHZi_~00@8p2!Mb}2&m4 z0dWcFY}F+X>U!Ig_znUf;2eQ=fuHXaVJ(1j#vzv=1XS|3KLuf<0HJCbwI_M6ECRg! zHBT)SzUy=v)*C!Ga;PW*B)l`7j9^nfJfPgCmVqD3L zydc0M0ezyZz5I>-cRO)IDWm9t;5i5C8%B6R^tPL|B*_0TulMr5aRA!5&yoIw$A)sf5CQij8s4Jz|V5d+75Y&Ytt3J8W>T?Mmsf9pdP)~^P zYH>;^KX98uD6-PaP3L~8^ajELxe&OkvPG7gKK;9h=GOwK@QDs z8*(op*X+Z6Q`h)uAvZ?s>M3Ql4QvzEfF%ZX1S|DaRCwY%0d&~Tv(rjWi&h+kpUNbV z7}V8v#UfN`fRj*UMqej0xbvPsW9#b<^mUf-W(rYn_F?{(IV+5b2ahfV*#c zS$USjVvz`Jp*j*Tk}jxun?T*eO`dChEx_AYQayqIpDLP^Pawdj%tcK{F)CA2Y4Ym} z>IT0&Ax!`RiKBMC0J7C65}edns!4q^C;f?EAdo=dF8zz3uCB^pP?tNeyh#k|Z~nfU z8oh*1AYdl}Ovl>^N_)woF%7T1LRX;2`oy5FK-(oT*{WM(h^RwL+oL1av|xkVL-M z)VRnDY<;{W+7+slco`IGI?T3{0QKTlO1j0)_?TEbS$nWZ!Ux`E&*{_Qnm z#T@@oWg=0HeYwH0p#Dj)&w8oX0?4E`aAxS_We%(nkN`&R0>V{@Xw(6P6qFNYs`8OA z#{#?))Kr*7r$V3LQVIlUv}UHmcokg=Y&3Fc1-I5hBkpR)O%?trx7US-p#B<#-Cyv` zo872Xko$cDb{ir?koY6xwGVykx$j5cGWs3VBInZ zC>x?>Mu0}{7BXpt%*=v0!V#E=`|85Mm5F3kkJ?r1oPd=F7eWHUm8s}3vWq>-j7{AH zSQ$sD+eLUs1XSCHt9L41*m|oIRy?H3jR1|@;>jkH-0Xrqyb}oH%9?k<5GX4GI$2r6 zqcI5T&cXC?E?X+OOa<%Q5N9nwDhA-NqXekqXQMeRrgIdWa?;088Jm@3E-ZC{0R4#; zb#4goPL?a)6YnHAdwhc(;C(7r6#>IQQ2BG>ACit)~VTL1a;?2*Wi3sN>inb0{`pGw0k$V0z^2`! zk{rPgH4{+vfDA$1`KqhxijgXod2Qxw!dieNcqkx*(E;3RPeMhJKQINa$YOKJXjS*) zEWpRRgh#uXOX2Nv+AVy}^8orhsd);@24KV#ys`_>3F}oI)ZM(M#znHo9_s`dWO+qE z-8BTIoF)N^2=SD_NIM(yVN)J~`Ba9{$}<}lyGTH_OW_$8%*VS{I}EO6M{cDPprF7m ziVd_Quq&%D*^TuuWtj|XT_vD}$Cwb*U8^Mq*RmtGPz3VVth_*qwE$d@Hwxt!SGk{X zFJ%G<>M3)PEf|>|W;INQC z2HNck?EZ}kkCS380NJP2Es)A6TC2{(?*sw{4RElq0B_ZRqe8lfhuMXst5Dh8=+Hps zpH!#|YBHMzbhDZqf-g=HQ2o7iMkNDPcB@l(kja(+rsHjC;CliAo4~#WNF*V^W=$F) zpi9DDj!F%3G>UJVFcr@aQB719eo$#k3I&vS+Sx_lL~VI4xwkB!vjuV%$t{5aav|U^ z7ej=!13{f1y6yN811V}HK*7aCzA1h&ou$Axe=BS)0K5Hx)$eL;SWft*g%{IsSmF`j zov0uwWuZ!g>G+hu;Mi*d+z3)f2V!0y#23B^Ft!Njd{b4vJcIIGu*-wk#GsBoI zCPGk86Aw-@0uFn)Sj4zIWGb^RZc(?_tse%BB=9Mlk?CNJnN*f zfq-2EC6A~pSz%GjP#4$SgiLb71qad$yYt^(-r{w4GTbl$lcAM0i z7~o^IS=_vPZRA}d1gf3@7o6C|;Y8XoJ#Sx$Gfu~foSBV{g4J0g5iikImpyP1w5dQvXplRy^OO?(Q5EX@$mTz`z9 z&VSuzOXM|Ik@&|5iM9kNs3qKlr%xRnZ%_Lc+w&^>&MsVr(Vh^@neQs|5AKLSfcjxi zQlpvY+{o8hhBYCmQ=>`v!46>Kg+Kr=QXm8bQXoL>HJWx-$4b-Ag5Sv$k}2^JyHH{G z&si{!qCH-TPQYf_5YSpboX}p}U%q^qPy%#S^XiLi%0uynu)`_uQ zNuv{XL1LzzU8q>;6PtVq=$dt)>qrH@7l7JFG-1`!AM;4~yTrBuK9&IZ$hU4O&NBSr zXT=qnIt=EfAPwYA;x4y#%|_=I+7Z+V0yh2$aBbiY|B_`bk^OCAOC}o=<88jL3lt z(pf3LHQ6!z1OZtP;4WBwGUnQqxE4TD!JP_$U1TS0wgEozsyp!-e4c{5o?fUip5>&VxK;QGo2Mf4e;w&l&4v@s5HLBD33)&O1V8`;93wz8qdLmr==u=Hl*lvn>-haTsAGy) zu##eb2*x0obO;6k5C8!XNF)%J_(egVpPXtrIdLrjA7)z!s1ln;^M7#=xFc1I%5CDN!1gMW?0lkz) zdBi6Aojj<&K9QIJpS%$;@g@m^KmY_l00fc~FeX2sk>7Wd+)DSF8W)MkE?&_mJntr+ zI%om`5C8#f5a6amwf3-jV&NtkktYx8@rkKi{=DJ)LvB9T0=R6DtOT%U-@;^N5sU!= z5C8#n5HPC44X3=Y+U80U;PD0uTQq`v52LF~PeCL@C8eVZi7zluX)(Ox+$w&-X->TKkV(WNHK|R(s0lxE2z{I;m2m}ET00He1 z(DEpqmAcio=n>QzjcbF49g$`&0DEhV(Y8SF9RxrC1VF%X0@RlpD3_1pIaQN`EsM9> zdV>IOOGCWxCh=5369|9+2&k5T)<^7b&9Wn?OH94V-IJ=%&P`A9!hA%=B zV54=N&`Ka51V8`;R6@Y05<{o<>86-L5hbrYBYRV2)ho|zSPTLn00N>CFp)MkD8lCE zW=RP`ilcTeVTu`25`tsA5QySM3WR_F2!MbJ3E;kZl0tp!4ReWS5!4e&NdM_il{P?n zGhhJ-fB*={l7LB;R!L)&B~`UvQ{y7jitLz!PZgbDCop6e3~lOyZ!D_Z6Kerd=YumK zASVJCw!c*xsmAJ513ayyizhKB-x7rbLK1N9%{4+=1lb?}0w5qg0kiZb$jSmsYSyG0 z)VU0)W=u^Wj=M|%&%e2h5CT8|1k^%+M(GCf#a}J{@Zkpyx-F^6K~PVPjC9A@QctsV z>Y*6~KmY_}MF6)blNLvcZ=^{~f}oyALSCO(MJKQFkc~B2XBoR=Er4u_1BQr5fJW>_ zQs*P0N+qbWq-CW0%ao zXQdqvttTy|My^c7Gf~k=<>8k|1Xx8jiKGi^KmY_lKyCy~WDo*+vQkMaptGduO~tb` z7WNM|NeF~;3q~YS4y7Of0w5p-0qXbkq&HLw-7?pi=Dl@hJA%5*OOVVnbJI}rw-gqF zfDM5)GykiLwE#9i@YPuYSTvV1IZMii-yBUhz;pL^@f`abW@3M1Ya2{rD}_D~009t? zf&dL@!bmS3ZA%$`y0^yD4eFd+OUm+bR3rkJk{1ay)PMj8NJoI1p)^Tnfvh#N7sJP< zXQ918J>9E=^c3N|%LFhb?=nIN009t?IRP`-hlO$}7m_9A!%2_Y71X(vcle|1N!f}0 zi%r8viLDg+KtKxwZe?562x|f4Q_?hI4jh6&Uv4DvAtmVf{VfPljU%#;I5;nT)u*K=-(A`sLQNhtF(n!DUpruDEI1VBKu z1gP&alJi*po_-B*XfW+iQ0JbCzns1eNFfpd+;A5OG}M3q2=GUM0=kZ*Me!$5)sln@ z>KrzQ6sQ`tJey5&S^EL zrX9y6Bf##p2S}zJia`JbK)_A{)K^7OQi}fA>>%J!KxgtC4(gbWx1$)ONx~j(*Gr=s zT0sB=Kp=er+~6ZL{gg<-5fDD8JF5sqBsc*!m4&y~2#y&FKmY`sAwU6LNBPXOW3!Kd z!&C1}tivO9&K5KGi4S=ZU{hLVd6@)jKmY`^PJjZsCoy27PB!?E+xF1SZ==0y0i?3s z;SoDC)TscE>3FHi*e<>8s4+#^l@f_S00cll90IIQVgnFt_7e~PjyiKPacK|t9ASU~qtwhNM3Z+1nqOF^BcRb!Jg1nI@N)Q7AAfO=v2=2TV_GKC<%Pzp1d36!O#3Hbq8fTbT%Af}XKtTBf zsL${uFU+)Kw9Zd)GM2n-yp7tq`vNO?u?j-OCNPg0sab5L&<6q_pgaOxK(~

={~Y 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 literal 0 HcmV?d00001 diff --git a/dist/icons/icon-96x96.png b/dist/icons/icon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..a9fdff80b0447675a1bc9c5bd9b280f25170aef0 GIT binary patch literal 48075 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 literal 0 HcmV?d00001 diff --git a/dist/manifest.json b/dist/manifest.json new file mode 100644 index 0000000..eebd31a --- /dev/null +++ b/dist/manifest.json @@ -0,0 +1,28 @@ +{ + "manifest_version": 2, + "name": "Mattermost Uno", + "version": "1.6.0", + "description": "Unofficial extension bringing some Slack-like features into Mattermost.", + "background": { + "scripts": [ + "background.js" + ] + }, + "browser_action": { + "default_title": "Mattermost Uno", + "default_icon": "icons/icon-32x32-bw.png" + }, + "permissions": [ + "" + ], + "icons": { + "16": "icons/icon-16x16.png", + "32": "icons/icon-32x32.png", + "48": "icons/icon-48x48.png", + "96": "icons/icon-96x96.png", + "128": "icons/icon-128x128.png" + }, + "default_locale": "en", + "homepage_url": "https://github.com/ivangabriele/mattermost-browser-extension", + "author": "Ivan Gabriele" +} diff --git a/package.json b/package.json index 5a64587..fb7fb53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mattermost-browser-extension", - "version": "1.5.0", + "version": "1.6.0", "description": "Mattermost Uno browsers extension.", "license": "MIT", "private": true,