diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..30e8f03 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Git-Auto-Deploy"] + path = deploy/Git-Auto-Deploy + url = https://github.com/olipo186/Git-Auto-Deploy.git diff --git a/deploy/Git-Auto-Deploy/.gitignore b/deploy/Git-Auto-Deploy/.gitignore new file mode 100644 index 0000000..f970650 --- /dev/null +++ b/deploy/Git-Auto-Deploy/.gitignore @@ -0,0 +1,86 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +GitAutoDeploy.conf.json +config.json +*.tc.json + +.idea +.DS_Store +._.DS_Store +.fuse* + +# Ignore +deb_dist +*.tar.gz +MANIFEST + +# dependencies +webui/node_modules + +# testing +webui/coverage + +# production +webui/build + +# misc +.DS_Store +.env +npm-debug.log diff --git a/deploy/Git-Auto-Deploy/.travis.yml b/deploy/Git-Auto-Deploy/.travis.yml new file mode 100644 index 0000000..47ec811 --- /dev/null +++ b/deploy/Git-Auto-Deploy/.travis.yml @@ -0,0 +1,14 @@ +language: python +python: + - "2.6" +# - "2.7" +# - "3.2" +# - "3.3" +# - "3.4" + - "3.5" +# - "3.5-dev" # 3.5 development branch +# - "nightly" # currently points to 3.6-dev +# command to install dependencies +install: "pip install -r requirements.txt" +# command to run tests +script: python test/test_parsers.py diff --git a/deploy/Git-Auto-Deploy/Dockerfile b/deploy/Git-Auto-Deploy/Dockerfile new file mode 100644 index 0000000..1451bdc --- /dev/null +++ b/deploy/Git-Auto-Deploy/Dockerfile @@ -0,0 +1,9 @@ +FROM google/python-runtime + +RUN apt-get update && \ + apt-get -y install openssh-client + +RUN mkdir $HOME/.ssh && chmod 600 $HOME/.ssh +COPY deploy_rsa /root/.ssh/id_rsa + +ENTRYPOINT ["/env/bin/python", "-u", "GitAutoDeploy.py", "--ssh-keyscan"] diff --git a/deploy/Git-Auto-Deploy/GitAutoDeploy.py b/deploy/Git-Auto-Deploy/GitAutoDeploy.py new file mode 100644 index 0000000..fed1679 --- /dev/null +++ b/deploy/Git-Auto-Deploy/GitAutoDeploy.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +if __name__ == '__main__': + import sys + import os + import gitautodeploy + sys.stderr.write("\033[1;33m[WARNING]\033[0;33m GitAutoDeploy.py is deprecated. Please use \033[1;33m'python gitautodeploy%s'\033[0;33m instead.\033[0m\n" % (' ' + ' '.join(sys.argv[1:])).rstrip()) + gitautodeploy.main() diff --git a/deploy/Git-Auto-Deploy/LICENSE b/deploy/Git-Auto-Deploy/LICENSE new file mode 100644 index 0000000..d18312d Binary files /dev/null and b/deploy/Git-Auto-Deploy/LICENSE differ diff --git a/deploy/Git-Auto-Deploy/Makefile b/deploy/Git-Auto-Deploy/Makefile new file mode 100644 index 0000000..f261888 --- /dev/null +++ b/deploy/Git-Auto-Deploy/Makefile @@ -0,0 +1,102 @@ +.PHONY: all detect install initsystem + +prefix = /opt/Git-Auto-Deploy/ + +#init_version := $(shell /sbin/init --version 2>&1) +#test_upstart := $(shell printf $(init_version) | grep -q upstart || grep -q upstart /proc/net/unix ; echo $$?) +#test_systemd := $(shell printf $(init_version) | grep -q systemd || grep -q systemd /proc/1/comm || grep -q systemd /proc/net/unix ; echo $$?) + +PYTHON ?= python2 + +# Debian distos to create packages for +DISTROS= \ + bionic \ + artful \ + xenial \ + trusty \ + precise + +# Package name and version +PACKAGE_NAME=$(shell python setup.py --name) +PACKAGE_VERSION=$(shell python setup.py --version) + +define version = + echo "hello" + exit 1 +endef + +all: + +clean: clean-pypi clean-deb + rm -rf *.tar.gz + +clean-pypi: + rm -rf *.egg-info + rm -rf dist/pypi + if [ -d "dist" ]; then rmdir --ignore-fail-on-non-empty dist; fi + +pypi: + $(PYTHON) setup.py sdist --dist-dir dist/pypi + +upload-pypi: + $(PYTHON) setup.py sdist --dist-dir dist/pypi register upload -r pypi + +clean-deb: + rm -rf dist/deb + rm -f dist/*.tar.gz + if [ -d "dist" ]; then rmdir --ignore-fail-on-non-empty dist; fi + +# Usage: make deb-source [DIST=] +deb-source: clean-deb + @- $(foreach DIST,$(DISTROS), \ + echo "Creating deb source package for dist $(DIST)" ; \ + echo "Make a debian source package using stdeb" ; \ + python setup.py --command-packages=stdeb.command sdist_dsc -x platforms/debian/stdeb.cfg --dist-dir dist/deb --debian-version $(DIST) --suite $(DIST) --upstream-version-suffix "~$(DIST)" ; \ + echo "Copy debian package config files" ; \ + cp -vr platforms/debian/stdeb/* dist/deb/$(PACKAGE_NAME)-$(PACKAGE_VERSION)~$(DIST)/debian/ ; \ + ) + +deb: clean-deb deb-source + @- $(foreach DIST,$(DISTROS), \ + echo "Creating unsigned deb package for dist $(DIST)" ; \ + echo "Build .deb package (without signing)" ; \ + cd dist/deb/$(PACKAGE_NAME)-$(PACKAGE_VERSION)~$(DIST) ; \ + dpkg-buildpackage -rfakeroot -uc -us ; \ + cd ../../../ ; \ + ) + +signed-deb: clean-deb deb-source + @- $(foreach DIST,$(DISTROS), \ + echo "Creating signed deb package for dist $(DIST)" ; \ + echo "Build .deb package (signed)" ; \ + cd dist/deb/$(PACKAGE_NAME)-$(PACKAGE_VERSION)~$(DIST) ; \ + debuild -S -sa ; \ + cd ../../../ ; \ + ) + +upload-deb: clean-deb signed-deb + @- $(foreach DIST,$(DISTROS), \ + echo "Upload signed debian package to ppa for dist $(DIST)" ; \ + dput ppa:olipo186/$(PACKAGE_NAME) dist/deb/$(PACKAGE_NAME)_$(PACKAGE_VERSION)~$(DIST)-$(DIST)_source.changes ; \ + ) + + +#initsystem: +#ifeq ($(test_upstart),0) +# @echo "Upstart detected!" +#else ifeq ($(test_systemd),0) +# @echo "Systemd detected!" +#else +# @echo "InitV supposed" +#endif +# @echo "Init script not installed - not yet implemented" + +#install: clean all +# @echo "Installing deploy script in $(prefix) ..." +# @echo "Installing deploy script in $(init_version) ..." +# @sudo mkdir $(prefix) &> /dev/null || true +# @sudo cp config.json.sample $(prefix)config.json +# @sudo cp -r gitautodeploy $(prefix)/ +# +# @echo "Installing run-on-startup scripts according to your init system ..." +# @make initsystem diff --git a/deploy/Git-Auto-Deploy/README.md b/deploy/Git-Auto-Deploy/README.md new file mode 100644 index 0000000..837cc1e --- /dev/null +++ b/deploy/Git-Auto-Deploy/README.md @@ -0,0 +1,128 @@ +[![Build Status](https://travis-ci.org/olipo186/Git-Auto-Deploy.svg?branch=master)](https://travis-ci.org/olipo186/Git-Auto-Deploy) +# What is it? + +Git-Auto-Deploy consists of a small HTTP server that listens for Webhook requests sent from GitHub, GitLab or Bitbucket servers. This application allows you to continuously and automatically deploy your projects each time you push new commits to your repository.

+ +![workflow](https://cloud.githubusercontent.com/assets/1056476/9344294/d3bc32a4-4607-11e5-9a44-5cd9b22e61d9.png) + +# How does it work? + +When commits are pushed to your Git repository, the Git server will notify ```Git-Auto-Deploy``` by sending an HTTP POST request with a JSON body to a pre-configured URL (your-host:8001). The JSON body contains detailed information about the repository and what event that triggered the request. ```Git-Auto-Deploy``` parses and validates the request, and if all goes well it issues a ```git pull```. + +Additionally, ```Git-Auto-Deploy``` can be configured to execute a shell command upon each successful ```git pull```, which can be used to trigger custom build actions or test scripts.

+ +# Getting started + +You can install ```Git-Auto-Deploy``` in multiple ways. Below are instructions for the most common methods. + +## Install from PPA (recommended for Ubuntu systems) + +[Using Debian? Have a look at this answer for instructions.](https://github.com/olipo186/Git-Auto-Deploy/issues/153) + +Add our PPA repository. + + sudo apt-get install software-properties-common + sudo add-apt-repository ppa:olipo186/git-auto-deploy + sudo apt-get update + +Install ```Git-Auto-Deploy``` using apt. + + sudo apt-get install git-auto-deploy + +Modify the configuration file to match your project setup. [Read more about the configuration options](./docs/Configuration.md). + + nano /etc/git-auto-deploy.conf.json + +Optional: Copy any private SSH key you wish to use to the home directory of GAD. + + sudo cp /path/to/id_rsa /etc/git-auto-deploy/.ssh/ + sudo chown -R git-auto-deploy:git-auto-deploy /etc/git-auto-deploy + +Start ```Git-Auto-Deploy``` and check it's status. + + service git-auto-deploy start + service git-auto-deploy status + +## Install from repository (recommended for other systems) + +When installing ```Git-Auto-Deploy``` from the repository, you'll need to make sure that Python (tested on version 2.7) and Git (tested on version 2.5.0) is installed on your system. + +Clone the repository. + + git clone https://github.com/olipo186/Git-Auto-Deploy.git + +Install the dependencies with [pip](http://www.pip-installer.org/en/latest/), a package manager for Python, by running the following command. + + sudo pip install -r requirements.txt + +If you don't have pip installed, try installing it by running this from the command +line: + + curl https://bootstrap.pypa.io/get-pip.py | python + +Copy of the sample config and modify it. [Read more about the configuration options](./docs/Configuration.md). Make sure that ```pidfilepath``` is writable for the user running the script, as well as all paths configured for your repositories. + + cd Git-Auto-Deploy + cp config.json.sample config.json + +Start ```Git-Auto-Deploy``` manually using; + + python -m gitautodeploy --config config.json + +To start ```Git-Auto-Deploy``` automatically on boot, open crontab in edit mode using ```crontab -e``` and add the entry below. + + @reboot /usr/bin/python -m /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode --quiet --config /path/to/git-auto-deploy.conf.json + +You can also configure ```Git-Auto-Deploy``` to start on boot using an init.d-script (for Debian and Sys-V like init systems) or a service for systemd.[Read more about starting Git-Auto-Deploy automatically using init.d or systemd](./docs/Start%20automatically%20on%20boot.md). + +## Install and run GAD under Windows +GAD runs under Windows but requires some requisites. + +1. Install Python 2.7 using the [Windows installer](https://www.python.org/downloads/). +2. Verify that Python is added to your [system PATH](https://technet.microsoft.com/en-us/library/cc772047(v=ws.11).aspx). Make sure ``C:\Python27`` and ``C:\Python27\Scripts`` is part of the PATH system environment variable. +3. Install pip using the [``get-pip.py`` script](https://pip.pypa.io/en/latest/installing/) +4. Install Git using the [official Git build for Windows](https://git-scm.com/download/win) +5. Verify that Git is added to your [system PATH](https://technet.microsoft.com/en-us/library/cc772047(v=ws.11).aspx). Make sure that ```C:\Program Files\Git\cmd``` is added (should have been added automatically by the installer) as well as ```C:\Program Files\Git\bin``` (*not* added by default). +6. Continue with the above instructions for [installing GAD from the repository](#install-from-repository-recommended-for-other-systems) + +## Alternative installation methods + +* [Install as a python module (experimental)](./docs/Install%20as%20a%20python%20module.md) +* [Install as a debian package (experimental)](./docs/Install%20as%20a%20debian%20package.md) +* [Start automatically on boot (init.d and systemd)](./docs/Start%20automatically%20on%20boot.md) + +## Command line options + +Below is a summarized list of the most common command line options. For a full list of available command line options, invoke the application with the argument ```--help``` or read the documentation article about [all available command line options, environment variables and config attributes](./docs/Configuration.md). + +Command line option | Environment variable | Config attribute | Description +---------------------- | -------------------- | ---------------- | -------------------------- +--daemon-mode (-d) | GAD_DAEMON_MODE | | Run in background (daemon mode) +--quiet (-q) | GAD_QUIET | | Supress console output +--config (-c) | GAD_CONFIG | | Custom configuration file +--pid-file | GAD_PID_FILE | pidfilepath | Specify a custom pid file +--log-file | GAD_LOG_FILE | logfilepath | Specify a log file +--host | GAD_HOST | host | Address to bind to +--port | GAD_PORT | port | Port to bind to + +## Getting webhooks from git +To make your git provider send notifications to ```Git-Auto-Deploy``` you will need to provide the hostname and port for your ```Git-Auto-Deploy``` instance. Instructions for the most common git providers is listed below. + +**GitHub** +1. Go to your repository -> Settings -> Webhooks and Services -> Add webhook +2. In "Payload URL", enter your hostname and port (your-host:8001) +3. Hit "Add webhook" + +**GitLab** +1. Go to your repository -> Settings -> Web hooks +2. In "URL", enter your hostname and port (your-host:8001) +3. Hit "Add Web Hook" + +**Bitbucket** +1. Go to your repository -> Settings -> Webhooks -> Add webhook +2. In "URL", enter your hostname and port (your-host:8001) +3. Hit "Save" + +# More documentation + +[Have a look in the *docs* directory](./docs), where you'll find more detailed documentation on configurations, alternative installation methods, and example workflows. diff --git a/deploy/Git-Auto-Deploy/config.json.sample b/deploy/Git-Auto-Deploy/config.json.sample new file mode 100755 index 0000000..959fe70 --- /dev/null +++ b/deploy/Git-Auto-Deploy/config.json.sample @@ -0,0 +1,70 @@ +{ + // HTTP server options + //"http-enabled": true, + //"http-host": "0.0.0.0", + //"http-port": 8001, + + // HTTPS server options + //"https-enabled": false, + //"https-host": "0.0.0.0", + //"https-port": 8002, + + // Web socket server options (used by web UI for real time updates) + //"wss-enabled": false, + //"wss-host": "0.0.0.0", + //"wss-port": 8003, + + // Web user interface options + //"web-ui-enabled": false, + //"web-ui-username": null, + //"web-ui-password": null, + //"web-ui-whitelist": ["127.0.0.1"], + + // TLS/SSL cert (necessary for HTTPS and web socket server to work) + //"ssl-key": null, // If specified, holds the private key + //"ssl-cert": "cert.pem", // Holds the public key or both the private and public keys + + // File to store a copy of the console output + "log-file": "~/gitautodeploy.log", + + // File to store the process id (pid) + "pid-file": "~/.gitautodeploy.pid", + + // Record all log levels by default + "log-level": "INFO", + + // Deploy commands that should be executed for all projects + //"global_deploy": [ + // "echo Deploy started!", + // "echo Deploy completed!" + //], + + "repositories": [ + { + "url": "https://github.com/olipo186/Git-Auto-Deploy.git", + "branch": "master", + "remote": "origin", + "path": "~/repositories/Git-Auto-Deploy", + "deploy": "echo deploying" + }, + { + "url": "https://github.com/github/gitignore", + "path": "~/repositories/gitignore" + }, + { + "url": "git@gitlab.com:gitlab-org/gitlab-ce.git", + "path": "~/repositories/gitignore" + }, + { + "url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy", + "deploy": "echo deploying after pull request", + "filters": [ + { + "type": "pull-request-filter", + "action": "closed", + "ref": "testing-branch" + } + ] + } + ] +} diff --git a/deploy/Git-Auto-Deploy/docs/Configuration.md b/deploy/Git-Auto-Deploy/docs/Configuration.md new file mode 100644 index 0000000..8b69e72 --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/Configuration.md @@ -0,0 +1,343 @@ +# Command line options and environment variables + +```Git-Auto-Deploy``` supports a number of configurable options. Some of them are available using command line options, where others are only configurable from the config file. Below is a list of the options made available from the command line. Every command line option has also a corresponding environment variable. In the cases where a corresponding config file attribute is available, that attribute name is listed. + +There is also support for supplying configuration options for up to one repository using environmetn variables. Variable names and descriptios are available in the section (Repository configuration using environment variables)[#eepository-configuration-using-environment-variables]. + +The list of available command line options can also be seen by invoke the application with the argument ```--help```. + +Command line option | Environment variable | Config attribute | Description +---------------------- | -------------------- | ---------------- | -------------------------- +--daemon-mode (-d) | GAD_DAEMON_MODE | | Run in background (daemon mode) +--quiet (-q) | GAD_QUIET | | Supress console output +--config (-c) | GAD_CONFIG | | Custom configuration file +--pid-file | GAD_PID_FILE | pidfilepath | Specify a custom pid file +--log-file | GAD_LOG_FILE | logfilepath | Specify a log file +--host | GAD_HOST | host | Address to bind to +--port | GAD_PORT | port | Port to bind to +--ssh-keyscan | GAD_SSH_KEYSCAN | | Scan repository hosts for ssh keys and add them to $HOME/.ssh/known_hosts + +# Configuration file options +The configuration file is formatted according to a `JSON` inspired format, with the additional feature of supporting inline comments. The possible root elements are +as follow: + + - **pidfilepath**: The path where `pid` files are kept. + - **logfilepath**: To enable logging, set this to a valid file path. + - **log-level**: Sets the threshold for the log output. Default value is NOTSET (all details). Recommended value is INFO (less details). + - **host**: What IP address to listen on. + - **port**: The port for the web server to listen on. + - **global_deploy**: An array of two specific commands or path to scripts + to be executed for all repositories defined: + - `[0]` = The pre-deploy script. + - `[1]` = The post-deploy script. + - **repositories**: An array of repository configurations. + +## Repositories +Repository configurations are comprised of the following elements: + + - **url**: The URL to the repository. + - **match-url**: An alternative URL used when matching incoming webhook requests (see https://github.com/olipo186/Git-Auto-Deploy/pull/148) + - **branch**: The branch which will be checked out. + - **remote**: The name of the remote to use. + - **path**: Path to clone the repository to. If omitted, the repository won't + be cloned, only the deploy scripts will be executed. + - **deploy**: A command to be executed. If `path` is set, the command is + executed after a successfull `pull`. + - **payload-filter**: A list of inclusive filters/rules that is applied to the request body of incoming web hook requests and determines whether the deploy command should be executed or not. See section *Filters* for more details. + - **header-filter**: A set of inclusive filters/rules that is applied to the request header of incoming web hook requests and determines whether the deploy command should be executed or not. See section *Filters* for more details. + - **secret-token**: The secret token set for your webhook (currently only implemented for [GitHub](https://developer.github.com/webhooks/securing/) and GitLab) + - **prepull**: A command to execute immediately before the `git pull`. This command could do something required for the ``git pull`` to succeed such as changing file permissions. + - **postpull**: A command to execute immediately after the `git pull`. After the **prepull** command is executed, **postpull** can clean up any changes made. + +## Filters +*(Currently only supported for GitHub and GitLab)* + +With filters, it is possible to trigger the deploy only if a set of specific criterias are met. The filter can be applied to the web hook request header (if specified using the *header-filter* option) or to the request body (*payload-filter*). + +### Allow web hooks with specific header values only (header-filter) + +Some Git providers will add custom HTTP headers in their web hook requests when sending them to GAD. Using a *header-filter*, you can configure GAD to only process web hooks that has a specific HTTP header specified. + +For example, if you'd like to only process requests that has the *X-Event-Key* header set to the value *pullrequest:fulfilled*, you could use the following config; + +```json +{ + ... + "repositories": [ + { + ... + "header-filter": { + "X-Event-Key": "pullrequest:fulfilled" + } + } + ] +} +``` + +If a header name is specified but with the value set to true, any request that has the header specified will pass without regard to the header value. + +```json +{ + ... + "repositories": [ + { + ... + "header-filter": { + "X-Event-Key": true + } + } + ] +} +``` + +### Allow web hooks with specific payload only (payload-filter) + +A web hook request typically contains a payload, or a request body, made up of a JSON object. The JSON object in the request body will follow a format choosen by the Git server. Thus, it's format will differ depending on whether you are using GitHub, GitLab, Bitbucket or any other Git provider. + +A *payload-filter* can be used to set specific criterias for which incoming web hook requests should actually trigger the deploy command. Filter can be setup to only trigger deploys when a commit is made to a specific branch, or when a pull request is closed and has a specific destination branch. + +Since the format of the payload differs depending on what Git provider you are using, you'll need to inspect the web hook request format yourself and write a filter that matches its structure. + +To specify a filter that should be applied further down the object tree, a dot notation (".") is used. For example, if the request body looks like this; +```json +{ + "action": "opened", + "number": 69, + "pull_request": { + "url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy/pulls/69", + "id": 61793882, + "html_url": "https://github.com/olipo186/Git-Auto-Deploy/pull/69", + "diff_url": "https://github.com/olipo186/Git-Auto-Deploy/pull/69.diff", + "patch_url": "https://github.com/olipo186/Git-Auto-Deploy/pull/69.patch", + "issue_url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy/issues/69", + "number": 69, + "state": "open", + "locked": false, + "title": "Refactoring. Fixed some imminent issues.", + "user": { + "login": "olipo186", + "id": 1056476, + "avatar_url": "https://avatars.githubusercontent.com/u/1056476?v=3", + "gravatar_id": "", + ... + }, + ... +} +``` + +You could specify the following filter, which would only trigger on pull requests created by olipo186. + +```json +{ + ... + "repositories": [ + { + ... + "payload-filter": [ + { + "action": "opened", + "pull_request.user.login": "olipo186" + } + ] + } + ] +} +``` + +## Legacy filters (older format) + +For example, deploy on `push` to the `master` branch only, ignore other branches. + +Filters are defined by providing keys/values to be looked up in the original +data sent by the web hook. + +For example, GitLab web hook data looks like this: + +```json + { + "object_kind":"build", + "ref":"master", + "tag":false, + ... + } +``` + +A filter can use `object_kind` and `ref` attributes for example to execute the +deploy action only on a `build` event on the `master` branch. + +### Examples + +#### GitHub + +The following example will trigger when a pull request with **master** as base is closed. The command `./prepull` and `./postpull` will execute immediately before and after the pull +```json +{ + "host": "0.0.0.0", + "port": 8080, + "global_deploy": [ + "echo Pre-deploy script", + "echo Post-deploy script" + ], + "repositories": [ + { + "url": "https://github.com/olipo186/Git-Auto-Deploy.git", + "branch": "master", + "remote": "origin", + "path": "~/repositories/Git-Auto-Deploy", + "deploy": "echo deploying", + "prepull": "chmod u+w config.json", + "postpull": "chmod u-w config.json", + "filters": [ + { + "action": "closed", + "pull_request": true, + "pull_request.base.ref": "master" + } + ] + } + ] +} +``` + +#### GitLab +*(Note: the filter examples below are valid for GitLab)* + +Execute pre-deploy script, don't `pull` the repository but execute a deploy +script, and finish with a post-deploy script. Execute only for `push` events on +the `master` branch. + +```json +{ + "pidfilepath": "~/.gitautodeploy.pid", + "host": "0.0.0.0", + "port": 8080, + "global_deploy": [ + "echo Pre-deploy script", + "echo Post-deploy script" + ], + "repositories": [ + { + "url": "http://gitlab/playground/hooktest.git", + "deploy": "echo deploying", + "filters": [ + { + "object_kind": "push", + "ref": "refs/heads/master" + } + ] + } + ] +} +``` + +Clone repository on `push` to `master`. + +```json +{ + "pidfilepath": "~/.gitautodeploy.pid", + "host": "0.0.0.0", + "port": 8080, + "repositories": [ + { + "url": "http://gitlab/playground/hooktest.git", + "branch": "master", + "remote": "origin", + "path": "~/repositories/hooktest", + "filters": [ + { + "object_kind": "push", + "ref": "refs/heads/master" + } + ] + } + ] +} +``` + +Execute script upon GitLab CI successful build of `master` branch. + +```json +{ + "pidfilepath": "~/.gitautodeploy.pid", + "host": "0.0.0.0", + "port": 8080, + "global_deploy": [ + "echo Pre-deploy script", + "echo Post-deploy script" + ], + "repositories": [ + { + "url": "http://gitlab/playground/hooktest.git", + "deploy": "echo deploying project!", + "filters": [ + { + "object_kind": "build", + "ref": "master", + "build_status": "success" + } + ] + } + ] +} +``` + +#### Bitbucket Server + +Get source using SSH. + +```json +{ + "host": "0.0.0.0", + "port": 8080, + "global_deploy": [ + "echo Pre-deploy script", + "echo Post-deploy script" + ], + "repositories": [ + { + "url": "ssh://git@bitbucket.example.com/KEY/Git-Auto-Deploy.git", + "match-url": "Git-Auto-Deploy", + "branch": "master", + "remote": "origin", + "path": "~/repositories/Git-Auto-Deploy", + "deploy": "echo deploying" + } + ] +} +``` + +Using HTTPS. + +```json +{ + "host": "0.0.0.0", + "port": 8080, + "global_deploy": [ + "echo Pre-deploy script", + "echo Post-deploy script" + ], + "repositories": [ + { + "url": "https://bitbucket.example.com/scm/KEY/Git-Auto-Deploy.git", + "match-url": "Git-Auto-Deploy", + "branch": "master", + "remote": "origin", + "path": "~/repositories/Git-Auto-Deploy", + "deploy": "echo deploying" + } + ] +} +``` +``` + +# Repository configuration using environment variables + +It's possible to configure up to one repository using environment variables. This can be useful in some specific use cases where a full config file is undesired. + +Environment variable | Description +-------------------- | -------------------------- +GAD_REPO_URL | Repository URL +GAD_REPO_BRANCH | +GAD_REPO_REMOTE | +GAD_REPO_PATH | Path to where ```Git-Auto-Deploy``` should clone and pull repository +GAD_REPO_DEPLOY | Deploy command diff --git a/deploy/Git-Auto-Deploy/docs/Continuous Delivery via Pull requests.md b/deploy/Git-Auto-Deploy/docs/Continuous Delivery via Pull requests.md new file mode 100644 index 0000000..047c76c --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/Continuous Delivery via Pull requests.md @@ -0,0 +1,23 @@ +# Continuous Delivery via Pull requests (GitHub only) + +![Workflow](./graphics/continuous_delivery_process.png) + +If you use continious delivery (such as this workflow) you may want to trigger deploy event when pull request is opened or closed. +You can follow next steps to implement CD process: +* Set repo "url" to ```"https://api.github.com"``` +* Add filter type "pull-request-filter" as described below +* Configure "action" that you want to listen +* Configure branch in which pull request trying to merge (variable "ref" below) + +Example +```json +"url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy", +"deploy": "echo deploying after pull request", +"filters": [ +{ + "action": "closed", + "pull_request": true, + "pull_request.base.ref": "testing-branch" +} +] +``` diff --git a/deploy/Git-Auto-Deploy/docs/Install as a debian package.md b/deploy/Git-Auto-Deploy/docs/Install as a debian package.md new file mode 100644 index 0000000..d77683e --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/Install as a debian package.md @@ -0,0 +1,51 @@ +# Install as debian package from PPA (experimental) + +Add our PPA + + add-apt-repository ppa:olipo186/git-auto-deploy + apt-get update + +Install the package + + apt-get install git-auto-deploy + +Make your changes to the configuration file + + nano /etc/git-auto-deploy.conf.json + +Run the application + + service git-auto-deploy start + service git-auto-deploy status + +# Install from .deb file (experimental) + +Below is instructions on how to create a debian (.deb) package using stdeb. You can follow the instructions below to build the .deb package, or use the prepared script (platforms/debian/scripts/create-debian-package.sh) that will do the same. Once the package is created, you can install it using ```dpkg -i```. A sample configuration file as well as a init.d start up script will be installed as part of the package. + +### Install dependencies + +Install stdeb and other dependencies + + apt-get install python-stdeb fakeroot python-all + +### Download and build + + git clone https://github.com/olipo186/Git-Auto-Deploy.git + cd Git-Auto-Deploy + make deb + +### Install + +When installing the package, a sample configuration file and a init.d start up script will be created. + + dpkg -i dist/deb/git-auto-deploy-.deb + +### Configuration + + nano /etc/git-auto-deploy.conf.json + +### Running the application + + service git-auto-deploy start + service git-auto-deploy status + diff --git a/deploy/Git-Auto-Deploy/docs/Install as a python module.md b/deploy/Git-Auto-Deploy/docs/Install as a python module.md new file mode 100644 index 0000000..ee3f2a1 --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/Install as a python module.md @@ -0,0 +1,41 @@ +# Install as a python module (experimental) + +## Download and install + +Install using [pip](http://www.pip-installer.org/en/latest/), a package manager for Python, by running the following command. + + pip install git-auto-deploy + +If you don't have pip installed, try installing it by running this from the command +line: + + curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python + +Or, you can [download the source code +(ZIP)](https://github.com/olipo186/Git-Auto-Deploy/zipball/master "Git-Auto-Deploy +source code") for `Git-Auto-Deploy` and then run: + + python setup.py install + +You may need to run the above commands with `sudo`. + +Once ```Git-Auto-Deploy``` has been installed as a python module, it can be started using the executable ```git-auto-deploy```. During installation with pip, the executable is usually installed in ```/usr/local/bin/git-auto-deploy```. This can vary depending on platform. + +## Configuration + +Copy the content of [config.json.sample](../config.json.sample) and save it anywhere you like, for example ```~/git-auto-deploy.conf.json```. Modify it to match your project setup. [Read more about the configuration options](../docs/Configuration.md). + +## Running the application + +Run the application using the executable ```git-auto-deploy``` which has been provided by pip. Provide the path to your configuration file as a command line argument. + + git-auto-deploy --config ~/git-auto-deploy.conf.json + +## Start automatically on boot using crontab + +The easiest way to configure your system to automatically start ```Git-Auto-Deploy``` after a reboot is using crontab. Open crontab in edit mode using ```crontab -e``` and add the entry below. + +When installing with pip, the executable ```git-auto-deploy``` is usually installed in ```/usr/local/bin/git-auto-deploy```. It is a good idea to verify the path to ```git-auto-deploy``` before adding the entry below. + + @reboot /usr/local/bin/git-auto-deploy --daemon-mode --quiet --config /path/to/git-auto-deploy.conf.json + diff --git a/deploy/Git-Auto-Deploy/docs/README.md b/deploy/Git-Auto-Deploy/docs/README.md new file mode 100644 index 0000000..51d629d --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/README.md @@ -0,0 +1,14 @@ +# Git-Auto-Deploy documentation + +# Documents + +* [Configuration options](./Configuration.md) +* [Install as a python module (experimental)](./Install as a python module.md) +* [Install as a debian package (experimental)](./Install as a debian package.md) +* [Start automatically on boot (init.d and systemd)](./Start automatically on boot.md) + +# Example workflows + +## Continuous Delivery via Pull requests (GitHub only) + +It's possible to configure Git-Auto-Deploy to trigger when pull requests are opened or closed on GitHub. To read more about this workflow and how to configure Git-Aut-Deploy here: [Continuous Delivery via Pull requests](./Continuous Delivery via Pull requests.md) diff --git a/deploy/Git-Auto-Deploy/docs/Start automatically on boot.md b/deploy/Git-Auto-Deploy/docs/Start automatically on boot.md new file mode 100644 index 0000000..7874d94 --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/Start automatically on boot.md @@ -0,0 +1,70 @@ +# Start automatically on boot + +```Git-Auto-Deploy``` can be automatically started at boot time using various techniques. Below you'll find a couple of suggested approaches with instructions. + +The following instructions assumes that you are running ```Git-Auto-Deploy``` from a clone of this repository. In such a case, ```Git-Auto-Deploy``` is started by invoking ```python -m``` and referencing the ```gitautodeploy``` python module which is found in the cloned repository. Such a command can look like ```python -m /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode```. + +If you have used any of the alternative installation methods (install with pip or as a debian package), you will instead start ```Git-Auto-Deploy``` using a installed executable. ```Git-Auto-Deploy``` would then be started using a command like ```git-auto-deploy --daemon-mode``` instead. If you have installed ```Git-Auto-Deploy``` in this way, you will need to modify the paths and commands used in the instructions below. + +## Crontab +The easiest way to configure your system to automatically start ```Git-Auto-Deploy``` after a reboot is using crontab. Open crontab in edit mode using ```crontab -e``` and add the following: + + @reboot /usr/bin/python -m /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode --quiet + +## Debian and Sys-V like init system. + +Copy the sample init script into ```/etc/init.d/``` and make it executable. + + cp platforms/linux/initfiles/debianLSBInitScripts/git-auto-deploy /etc/init.d/ + chmod 755 /etc/init.d/git-auto-deploy + +**Important:** The init script assumes that you have ```Git-Auto-Deploy``` installed in ```/opt/Git-Auto-Deploy/``` and that the ```pidfilepath``` config option is set to ```/var/run/git-auto-deploy.pid```. If this is not the case, edit the ```git-auto-deploy``` init script and modify ```DAEMON```, ```PWD``` and ```PIDFILE```. + +**Important:** The init script will run GAD as the ```root``` user by default, which is convenient but not secure. The recommended way to run GAD is to set up a separate user and modify the init script to run GAD as that user. When running GAD as a user other than root, you will need to make sure that the correct permissions are set on all directories and files that GAD requires access to (such as the path specified in the variable PIDFILE and LOGFIE in the init script). + +Now you need to add the correct symbolic link to your specific runlevel dir to get the script executed on each start up. On Debian_Sys-V just do; + + update-rc.d git-auto-deploy defaults + +Fire it up and verify; + + service git-auto-deploy start + service git-auto-deploy status + +## Systemd + +Copy the sample systemd service file ```git-auto-deploy.service``` into ```/etc/systemd/system```; + + cp platforms/linux/initfiles/systemd/git-auto-deploy.service /etc/systemd/system + +Create the user and group specified in git-auto-deploy.service (```www-data```) if those do not exist already. + + useradd -U www-data + +This init script assumes that you have ```Git-Auto-Deploy``` installed in ```/opt/Git-Auto-Deploy/```. If this is not the case, edit the ```git-auto-deploy.service``` service file and modify ```ExecStart``` and ```WorkingDirectory```. + +Now, reload daemons and fire ut up; + + systemctl daemon-reload + systemctl start git-auto-deploy + +Make is start automatically on system boot; + + systemctl enable gitautodeploy + +## CentOS 7 + +Have a look at [this script](../platforms/linux/initfiles/centos) which was kindly provided by https://github.com/olipo186/Git-Auto-Deploy/issues/192. Usage: + +Start: + + GitAutoDeploy_Service.sh start + +Stop: + + GitAutoDeploy_Service.sh stop + +Stop: + + GitAutoDeploy_Service.sh restart + diff --git a/deploy/Git-Auto-Deploy/docs/Useful commands.md b/deploy/Git-Auto-Deploy/docs/Useful commands.md new file mode 100644 index 0000000..41e0da4 --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/Useful commands.md @@ -0,0 +1,14 @@ + +# Create debian package +apt-get install python-stdeb fakeroot python-all + +https://pypi.python.org/pypi/stdeb/0.8.5 +python setup.py --command-packages=stdeb.command –package=git-auto-deploy bdist_deb +python setup.py --command-packages=stdeb.command sdist_dsc bdist_deb + + +# Debianize +python setup.py --command-packages=stdeb.command debianize + +# deb source +add-apt-repository ppa:olipo186/git-auto-deploy diff --git a/deploy/Git-Auto-Deploy/docs/add-ssh-keys.md b/deploy/Git-Auto-Deploy/docs/add-ssh-keys.md new file mode 100644 index 0000000..9f94292 --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/add-ssh-keys.md @@ -0,0 +1,22 @@ +# How to add your SSH keys to Git-Auto-Deploy + +1. Copy your ssh keys from your account to /etc/git-auto-deploy/.ssh/ + +```cp -R ~/.ssh /etc/git-auto-deploy/``` + +2. Add gitlab, github or your hostname to the known_hosts file, eg. + +```ssh-keyscan -t rsa gitlab.com >> /etc/git-auto-deploy/.ssh/known_hosts``` + +3. Add read and write permissions to /etc/git-auto-deploy + +``` +chown -R git-auto-deploy:git-auto-deploy /etc/git-auto-deploy +chmod -R 700 /etc/git-auto-deploy/.ssh/* +``` + +4. Add write permissions to your repository path + +```chown -R git-auto-deploy:git-auto-deploy /home/myrepo``` + +Make sure you use your ssh url in your config. diff --git a/deploy/Git-Auto-Deploy/docs/graphics/continuous_delivery_process.gliffy b/deploy/Git-Auto-Deploy/docs/graphics/continuous_delivery_process.gliffy new file mode 100644 index 0000000..13e1fca --- /dev/null +++ b/deploy/Git-Auto-Deploy/docs/graphics/continuous_delivery_process.gliffy @@ -0,0 +1 @@ +{"contentType":"application/gliffy+json","version":"1.3","stage":{"background":"#FFFFFF","width":790,"height":426,"nodeIndex":182,"autoFit":true,"exportBorder":false,"gridOn":true,"snapToGrid":true,"drawingGuidesOn":true,"pageBreaksOn":false,"printGridOn":false,"printPaper":"LETTER","printShrinkToFit":false,"printPortrait":true,"maxWidth":5000,"maxHeight":5000,"themeData":null,"viewportType":"default","fitBB":{"min":{"x":97.44999999999999,"y":52},"max":{"x":790,"y":426}},"printModel":{"pageSize":"Letter","portrait":true,"fitToOnePage":false,"displayPageBreaks":false},"objects":[{"x":370.0,"y":253.0,"rotation":0.0,"id":91,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.uml.uml_v1.default.implements","order":26,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":153,"py":1.0,"px":0.5}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":54,"py":0.0,"px":0.5}}},"graphic":{"type":"Line","Line":{"strokeWidth":1.0,"strokeColor":"#000000","fillColor":"none","dashStyle":"8.0,2.0","startArrow":0,"endArrow":4,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[160.0,-75.0],[160.0,-10.999161176776454],[160.0,53.00167764644709],[160.0,117.0025164696707]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":92,"width":94.0,"height":56.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.44791079607326306,"linePerpValue":0.0,"cardinalityType":null,"html":"

GitHib Webhook

triggers

Pull Request

action "closed"

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":479.01697879669456,"y":370.0,"rotation":0.0,"id":54,"width":100.0,"height":50.0,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","order":5,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2.0,"strokeColor":"#333333","fillColor":"#ffd966","gradient":true,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":55,"width":96.0,"height":28.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

GitAutoDeploy

test build

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":81.0,"y":62.0,"rotation":0.0,"id":61,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.uml.uml_v1.default.generalization","order":11,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":58,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":149,"py":0.5,"px":0.0}}},"graphic":{"type":"Line","Line":{"strokeWidth":1.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":4,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[57.900000000000006,163.0],[94.93333333333334,163.0],[131.96666666666667,163.0],[169.0,163.0]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":62,"width":47.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.40380291663420176,"linePerpValue":null,"cardinalityType":null,"html":"

Commit

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":91.0,"y":72.0,"rotation":0.0,"id":72,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.uml.uml_v1.default.generalization","order":20,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":69,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":52,"py":0.5,"px":0.0}}},"graphic":{"type":"Line","Line":{"strokeWidth":1.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":4,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[47.89999999999998,3.0],[84.93333333333334,3.0],[121.96666666666667,3.0],[159.0,3.0]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":73,"width":47.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.40380291663420176,"linePerpValue":null,"cardinalityType":null,"html":"

Commit

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":101.0,"y":82.0,"rotation":0.0,"id":74,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.uml.uml_v1.default.generalization","order":23,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":67,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":145,"py":0.5,"px":0.0}}},"graphic":{"type":"Line","Line":{"strokeWidth":1.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":4,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[37.89999999999998,73.0],[74.93333333333334,73.0],[111.96666666666667,73.0],[149.0,73.0]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":75,"width":47.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.40380291663420176,"linePerpValue":null,"cardinalityType":null,"html":"

Commit

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":353.14285714285717,"y":77.71428571428572,"rotation":0.0,"id":155,"width":137.71428571428567,"height":49.714285714285715,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":64,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":52,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":153,"py":0.0,"px":0.5}}},"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[-3.142857142857167,-2.7142857142857224],[176.85714285714283,-2.7142857142857224],[176.85714285714283,54.28571428571428]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":157,"width":75.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.336382768363788,"linePerpValue":null,"cardinalityType":null,"html":"

Pull Request

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":363.14285714285717,"y":87.71428571428572,"rotation":0.0,"id":158,"width":137.71428571428567,"height":49.714285714285715,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":67,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":145,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":153,"py":0.5,"px":0.0}}},"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[-13.142857142857167,67.28571428571428],[30.190476190476147,67.28571428571428],[73.52380952380952,67.28571428571428],[116.85714285714283,67.28571428571428]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":159,"width":75.0,"height":14.0,"uid":null,"order":69,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.47692307692307695,"linePerpValue":0.0,"cardinalityType":null,"html":"

Pull Request

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":626.8571428571429,"y":186.28571428571428,"rotation":0.0,"id":160,"width":137.71428571428567,"height":49.714285714285715,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":70,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":149,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":153,"py":1.0,"px":0.5}}},"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[-276.8571428571429,38.71428571428572],[-96.85714285714289,38.71428571428572],[-96.85714285714289,-8.285714285714278]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":161,"width":75.0,"height":14.0,"uid":null,"order":72,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.336382768363788,"linePerpValue":null,"cardinalityType":null,"html":"

Pull Request

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":120.00000000000001,"y":210.0,"rotation":0.0,"id":58,"width":18.900000000000002,"height":30.0,"uid":"com.gliffy.shape.uml.uml_v1.default.actor","order":8,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.actor.uml_v1","strokeWidth":1.0,"strokeColor":"#000000","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":60,"width":62.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Developer

","tid":null,"valign":"middle","vposition":"below","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":119.99999999999999,"y":140.0,"rotation":0.0,"id":67,"width":18.900000000000002,"height":30.0,"uid":"com.gliffy.shape.uml.uml_v1.default.actor","order":14,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.actor.uml_v1","strokeWidth":1.0,"strokeColor":"#000000","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":68,"width":62.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Developer

","tid":null,"valign":"middle","vposition":"below","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":119.99999999999999,"y":60.0,"rotation":0.0,"id":69,"width":18.900000000000002,"height":30.0,"uid":"com.gliffy.shape.uml.uml_v1.default.actor","order":17,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.actor.uml_v1","strokeWidth":1.0,"strokeColor":"#000000","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":70,"width":62.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Developer

","tid":null,"valign":"middle","vposition":"below","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":620.0,"y":380.0,"rotation":0.0,"id":166,"width":18.900000000000002,"height":30.0,"uid":"com.gliffy.shape.uml.uml_v1.default.actor","order":73,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.actor.uml_v1","strokeWidth":1.0,"strokeColor":"#000000","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":167,"width":22.0,"height":14.0,"uid":null,"order":75,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

QA

","tid":null,"valign":"middle","vposition":"below","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":380.0,"y":263.0,"rotation":0.0,"id":168,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.uml.uml_v1.default.implements","order":76,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":54,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":166,"py":0.5,"px":0.0}}},"graphic":{"type":"Line","Line":{"strokeWidth":1.0,"strokeColor":"#000000","fillColor":"none","dashStyle":"8.0,2.0","startArrow":0,"endArrow":4,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[199.0169787966945,132.0],[212.67798586446304,132.0],[226.33899293223146,132.0],[240.0,132.0]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":390.0,"y":273.0,"rotation":0.0,"id":171,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.uml.uml_v1.default.implements","order":77,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":166,"py":0.0,"px":0.5}}},"graphic":{"type":"Line","Line":{"strokeWidth":1.0,"strokeColor":"#000000","fillColor":"none","dashStyle":"8.0,2.0","startArrow":0,"endArrow":4,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[239.45000000000005,107.0],[239.45000000000005,0.7142857142857224],[239.1428571428571,0.7142857142857224],[239.1428571428571,-105.57142857142858]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":555.7142857142858,"y":143.14285714285714,"rotation":0.0,"id":172,"width":137.71428571428567,"height":49.714285714285715,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":78,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":153,"py":0.5,"px":1.0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":176,"py":0.5,"px":0.0}}},"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[24.28571428571422,11.857142857142861],[60.95238095238085,11.857142857142861],[97.61904761904759,11.857142857142861],[134.28571428571422,11.857142857142861]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":173,"width":75.0,"height":14.0,"uid":null,"order":80,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.435087068455616,"linePerpValue":0.0,"cardinalityType":null,"html":"

Pull Request

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":380.0,"y":263.0,"rotation":0.0,"id":178,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.uml.uml_v1.default.implements","order":89,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":176,"py":1.0,"px":0.5}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":180,"py":0.0,"px":0.5}}},"graphic":{"type":"Line","Line":{"strokeWidth":1.0,"strokeColor":"#000000","fillColor":"none","dashStyle":"8.0,2.0","startArrow":0,"endArrow":4,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[360.0,-85.0],[360.0,-21.0],[360.0,43.0],[360.0,107.0]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":179,"width":94.0,"height":56.0,"uid":null,"order":91,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"both","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":0.4329896907216496,"linePerpValue":0.0,"cardinalityType":null,"html":"

GitHib Webhook

triggers

Pull Request

action "closed"

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":690.0,"y":370.0,"rotation":0.0,"id":180,"width":100.0,"height":50.0,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","order":92,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2.0,"strokeColor":"#333333","fillColor":"#93c47d","gradient":true,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":181,"width":96.0,"height":42.0,"uid":null,"order":94,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

GitAutoDeploy

Production

build

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":480.0,"y":132.0,"rotation":0.0,"id":153,"width":100.0,"height":46.0,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","order":58,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2.0,"strokeColor":"#000000","fillColor":"#999999","gradient":true,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":1.9999999999999993,"y":0.0,"rotation":0.0,"id":154,"width":95.99999999999999,"height":28.0,"uid":null,"order":61,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

            Branch

            «testing»

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":490.0,"y":140.0,"rotation":0.0,"id":152,"width":39.01697879669456,"height":30.0,"uid":"com.gliffy.shape.basic.basic_v1.default.svg","order":63,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Svg","Svg":{"embeddedResourceId":0,"strokeWidth":2.0,"strokeColor":"#000000","dropShadow":true,"shadowX":5.0,"shadowY":5.0}},"linkMap":[],"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":690.0,"y":132.0,"rotation":0.0,"id":176,"width":100.0,"height":46.0,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","order":83,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2.0,"strokeColor":"#333333","fillColor":"#999999","gradient":true,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":1.9999999999999993,"y":0.0,"rotation":0.0,"id":177,"width":95.99999999999999,"height":28.0,"uid":null,"order":86,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

            Branch

            «master»

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":700.0,"y":140.0,"rotation":0.0,"id":175,"width":39.01697879669456,"height":30.0,"uid":"com.gliffy.shape.basic.basic_v1.default.svg","order":88,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Svg","Svg":{"embeddedResourceId":0,"strokeWidth":2.0,"strokeColor":"#000000","dropShadow":true,"shadowX":5.0,"shadowY":5.0}},"linkMap":[],"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":250.0,"y":52.0,"rotation":0.0,"id":52,"width":100.0,"height":46.0,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","order":1,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2.0,"strokeColor":"#333333","fillColor":"#999999","gradient":true,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":1.9999999999999987,"y":0.0,"rotation":0.0,"id":53,"width":95.99999999999996,"height":28.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

               Own 

               Branch

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":260.0,"y":60.0,"rotation":0.0,"id":137,"width":39.01697879669456,"height":30.0,"uid":"com.gliffy.shape.basic.basic_v1.default.svg","order":38,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Svg","Svg":{"embeddedResourceId":0,"strokeWidth":2.0,"strokeColor":"#000000","dropShadow":true,"shadowX":5.0,"shadowY":5.0}},"linkMap":[],"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":250.0,"y":132.0,"rotation":0.0,"id":145,"width":100.0,"height":46.0,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","order":42,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2.0,"strokeColor":"#333333","fillColor":"#999999","gradient":true,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":1.9999999999999993,"y":0.0,"rotation":0.0,"id":146,"width":95.99999999999999,"height":28.0,"uid":null,"order":45,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

               Own 

               Branch

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":260.0,"y":140.0,"rotation":0.0,"id":144,"width":39.01697879669456,"height":30.0,"uid":"com.gliffy.shape.basic.basic_v1.default.svg","order":47,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Svg","Svg":{"embeddedResourceId":0,"strokeWidth":2.0,"strokeColor":"#000000","dropShadow":true,"shadowX":5.0,"shadowY":5.0}},"linkMap":[],"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":250.0,"y":202.0,"rotation":0.0,"id":149,"width":100.0,"height":46.0,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","order":50,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2.0,"strokeColor":"#333333","fillColor":"#999999","gradient":true,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":1.9999999999999993,"y":0.0,"rotation":0.0,"id":150,"width":95.99999999999999,"height":28.0,"uid":null,"order":53,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

               Own 

               Branch

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"hidden":false,"layerId":"Z1TPI7X0OTpK"},{"x":260.0,"y":210.0,"rotation":0.0,"id":148,"width":39.01697879669456,"height":30.0,"uid":"com.gliffy.shape.basic.basic_v1.default.svg","order":55,"lockAspectRatio":true,"lockShape":false,"graphic":{"type":"Svg","Svg":{"embeddedResourceId":0,"strokeWidth":2.0,"strokeColor":"#000000","dropShadow":true,"shadowX":5.0,"shadowY":5.0}},"linkMap":[],"children":[],"hidden":false,"layerId":"Z1TPI7X0OTpK"}],"layers":[{"guid":"Z1TPI7X0OTpK","order":0,"name":"Layer 0","active":true,"locked":false,"visible":true,"nodeIndex":95}],"shapeStyles":{"com.gliffy.shape.flowchart.flowchart_v1.default":{"fill":"#999999","stroke":"#000000","strokeWidth":2,"gradient":true},"com.gliffy.shape.uml.uml_v2.deployment":{"fill":"#FFFFFF","stroke":"#000000","strokeWidth":2}},"lineStyles":{"global":{"endArrow":2}},"textStyles":{"global":{}}},"metadata":{"title":"untitled","revision":0,"exportBorder":false,"loadPosition":"default","libraries":["com.gliffy.libraries.uml.uml_v1.default","com.gliffy.libraries.uml.uml_v2.deployment","com.gliffy.libraries.flowchart.flowchart_v1.default","com.gliffy.libraries.swimlanes.swimlanes_v1.default"],"autosaveDisabled":false,"lastSerialized":1456661255923,"analyticsProduct":"Online"},"embeddedResources":{"index":1,"resources":[{"id":0,"mimeType":"image/svg+xml","data":"\n\n","width":511.0011145187177,"height":392.9067269775449,"x":0.49915941210551446,"y":59.547654341977314}]}} \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/docs/graphics/continuous_delivery_process.png b/deploy/Git-Auto-Deploy/docs/graphics/continuous_delivery_process.png new file mode 100644 index 0000000..2dc01b4 Binary files /dev/null and b/deploy/Git-Auto-Deploy/docs/graphics/continuous_delivery_process.png differ diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/__init__.py b/deploy/Git-Auto-Deploy/gitautodeploy/__init__.py new file mode 100644 index 0000000..81e2119 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from .gitautodeploy import * +from .cli import * +from .parsers import * diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/__main__.py b/deploy/Git-Auto-Deploy/gitautodeploy/__main__.py new file mode 100644 index 0000000..f787d8e --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/__main__.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +if __name__ == '__main__': + + if __package__ != 'gitautodeploy': + import sys + print("Critical - GAD must be started as a python module, for example using python -m gitautodeploy") + sys.exit() + + from gitautodeploy import main + import sys + import os + sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) + main() + +else: + from gitautodeploy import main \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/cli/__init__.py b/deploy/Git-Auto-Deploy/gitautodeploy/cli/__init__.py new file mode 100644 index 0000000..27c9ec6 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/cli/__init__.py @@ -0,0 +1 @@ +from .config import * diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/cli/config.py b/deploy/Git-Auto-Deploy/gitautodeploy/cli/config.py new file mode 100644 index 0000000..1a6c8c1 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/cli/config.py @@ -0,0 +1,503 @@ +class ConfigFileNotFoundException(Exception): + pass + + +class ConfigFileInvalidException(Exception): + pass + + +def get_config_defaults(): + """Get the default configuration values.""" + + config = {} + + # Supress console output + config['quiet'] = False + + # Run in daemon mode + config['daemon-mode'] = False + + # File containing additional config options + config['config'] = None + + # File to store a copy of the console output + config['log-file'] = None + + # File to store the process id (pid) + config['pid-file'] = '~/.gitautodeploy.pid' + + # HTTP server options + config['http-enabled'] = True + config['http-host'] = '0.0.0.0' + config['http-port'] = 8001 + + # HTTPS server options + config['https-enabled'] = True + config['https-host'] = '0.0.0.0' + config['https-port'] = 8002 + + # Web socket server options (used by web UI for real time updates) + config['wss-enabled'] = False # Disabled by default until authentication is in place + config['wss-host'] = '0.0.0.0' + config['wss-port'] = 8003 + + # TLS/SSL cert (necessary for HTTPS and web socket server to work) + config['ssl-key'] = None # If specified, holds the private key + config['ssl-cert'] = '~/cert.pem' # Holds the public key or both the private and public keys + + # Web user interface options + config['web-ui-enabled'] = False # Disabled by default until authentication is in place + config['web-ui-username'] = None + config['web-ui-password'] = None + config['web-ui-whitelist'] = ['127.0.0.1'] + config['web-ui-require-https'] = True + config['web-ui-auth-enabled'] = True + config['web-ui-prevent-root'] = True + + # Record all log levels by default + config['log-level'] = 'NOTSET' + + # Other options + config['intercept-stdout'] = True + config['ssh-keyscan'] = False + config['allow-root-user'] = False + + # Log incoming webhook requests in a way they can be used as test cases + config['log-test-case'] = False + config['log-test-case-dir'] = None + + return config + + +def rename_legacy_attribute_names(config): + import logging + logger = logging.getLogger() + + rewrite_map = { + 'ssl': 'https-enabled', + 'ssl-pem-file': 'ssl-cert', + 'host': 'http-host', + 'port': 'http-port', + 'pidfilepath': 'pid-file', + 'logfilepath': 'log-file' + } + + for item in rewrite_map.items(): + old_name, new_name = item + if old_name in config: + config[new_name] = config[old_name] + del config[old_name] + print("Config option '%s' is deprecated. Please use '%s' instead." % (old_name, new_name)) + + return config + + +def get_config_from_environment(): + """Get configuration values provided as environment variables.""" + import os + + config = {} + + if 'GAD_QUIET' in os.environ: + config['quiet'] = True + + if 'GAD_DAEMON_MODE' in os.environ: + config['daemon-mode'] = True + + if 'GAD_CONFIG' in os.environ: + config['config'] = os.environ['GAD_CONFIG'] + + if 'GAD_SSH_KEYSCAN' in os.environ: + config['ssh-keyscan'] = True + + if 'GAD_SSL_KEY' in os.environ: + config['ssl-key'] = os.environ['GAD_SSL_KEY'] + + if 'GAD_SSL_CERT' in os.environ: + config['ssl-cert'] = os.environ['GAD_SSL_CERT'] + + if 'GAD_PID_FILE' in os.environ: + config['pid-file'] = os.environ['GAD_PID_FILE'] + + if 'GAD_LOG_FILE' in os.environ: + config['log-file'] = os.environ['GAD_LOG_FILE'] + + if 'GAD_HOST' in os.environ: + config['http-host'] = os.environ['GAD_HOST'] + + if 'GAD_HTTP_HOST' in os.environ: + config['http-host'] = os.environ['GAD_HTTP_HOST'] + + if 'GAD_HTTPS_HOST' in os.environ: + config['https-host'] = os.environ['GAD_HTTPS_HOST'] + + if 'GAD_PORT' in os.environ: + config['http-port'] = int(os.environ['GAD_PORT']) + + if 'GAD_HTTP_PORT' in os.environ: + config['http-port'] = int(os.environ['GAD_HTTP_PORT']) + + if 'GAD_HTTPS_PORT' in os.environ: + config['https-port'] = int(os.environ['GAD_HTTPS_PORT']) + + return config + + +def get_config_from_argv(argv): + import argparse + + parser = argparse.ArgumentParser() + + parser.add_argument("-d", "--daemon-mode", + help="run in background (daemon mode)", + dest="daemon-mode", + default=None, + action="store_true") + + parser.add_argument("-q", "--quiet", + help="supress console output", + dest="quiet", + default=None, + action="store_true") + + parser.add_argument("-c", "--config", + help="custom configuration file", + dest="config", + type=str) + + parser.add_argument("--ssh-keyscan", + help="scan repository hosts for ssh keys", + dest="ssh-keyscan", + default=None, + action="store_true") + + parser.add_argument("--pid-file", + help="specify a custom pid file", + dest="pid-file", + type=str) + + parser.add_argument("--log-file", + help="specify a log file", + dest="log-file", + type=str) + + parser.add_argument("--log-level", + help="specify log level", + dest="log-level", + type=str) + + parser.add_argument("--host", + help="address to bind http server to", + dest="http-host", + type=str) + + #parser.add_argument("--http-host", + # help="address to bind http server to", + # dest="http-host", + # type=str) + + #parser.add_argument("--https-host", + # help="address to bind https server to", + # dest="https-host", + # type=str) + + parser.add_argument("--port", + help="port to bind http server to", + dest="http-port", + type=int) + + #parser.add_argument("--http-port", + # help="port to bind http server to", + # dest="http-port", + # type=int) + + #parser.add_argument("--https-port", + # help="port to bind http server to", + # dest="https-port", + # type=int) + + parser.add_argument("--ws-port", + help="port to bind web socket server to", + dest="web-ui-web-socket-port", + type=int) + + parser.add_argument("--ssl", + help="enable https", + dest="https-enabled", + default=None, + action="store_true") + + parser.add_argument("--ssl-key", + help="path to ssl key file", + dest="ssl-key", + type=str) + + parser.add_argument("--ssl-cert", + help="path to ssl cert file", + dest="ssl-cert", + type=str) + + parser.add_argument("--allow-root-user", + help="allow running as root user", + dest="allow-root-user", + default=None, + action="store_true") + + + config = vars(parser.parse_args(argv)) + + # Delete entries for unprovided arguments + del_keys = [] + for key in config: + if config[key] is None: + del_keys.append(key) + + for key in del_keys: + del config[key] + + return config + + +def find_config_file(target_directories=None): + """Attempt to find a path to a config file. Provided paths are scanned + for *.conf(ig)?.json files.""" + import os + import re + import logging + logger = logging.getLogger() + + if not target_directories: + return + + # Remove duplicates + target_directories = list(set(target_directories)) + + # Look for a *conf.json or *config.json + for dir in target_directories: + + if not os.access(dir, os.R_OK): + continue + + for item in os.listdir(dir): + if re.match(r".*conf(ig)?\.json$", item): + path = os.path.realpath(os.path.join(dir, item)) + logger.info("Using '%s' as config" % path) + return path + + +def get_config_from_file(path): + """Get configuration values from config file.""" + import logging + import os + logger = logging.getLogger() + + config_file_path = os.path.realpath(path) + logger.info('Using custom configuration file \'%s\'' % config_file_path) + + # Read config data from json file + if config_file_path: + config_data = read_json_file(config_file_path) + else: + logger.info('No configuration file found or specified. Using default values.') + config_data = {} + + return config_data + + +def read_json_file(file_path): + import json + import logging + import re + import errno + + try: + json_string = open(file_path).read() + + except IOError as e: + if e.errno == errno.ENOENT: + raise ConfigFileNotFoundException(file_path) + else: + raise e + + except Exception as e: + raise e + + try: + # Remove commens from JSON (makes sample config options easier) + regex = r'\s*(#|\/{2}).*$' + regex_inline = r'(:?(?:\s)*([A-Za-z\d\.{}]*)|((?<=\").*\"),?)(?:\s)*(((#|(\/{2})).*)|)$' + lines = json_string.split('\n') + + for index, line in enumerate(lines): + if re.search(regex, line): + if re.search(r'^' + regex, line, re.IGNORECASE): + lines[index] = "" + elif re.search(regex_inline, line): + lines[index] = re.sub(regex_inline, r'\1', line) + + data = json.loads('\n'.join(lines)) + + except ValueError as e: + raise ConfigFileInvalidException(file_path) + + except Exception as e: + raise e + + return data + + +def init_config(config): + """Initialize config by filling out missing values etc.""" + + import os + import re + import logging + from ..models import Project + logger = logging.getLogger() + + # Translate any ~ in the path into /home/ + if 'pid-file' in config and config['pid-file']: + config['pid-file'] = os.path.expanduser(config['pid-file']) + + if 'log-file' in config and config['log-file']: + config['log-file'] = os.path.expanduser(config['log-file']) + + if 'ssl-cert' in config and config['ssl-cert']: + config['ssl-cert'] = os.path.expanduser(config['ssl-cert']) + + if 'ssl-key' in config and config['ssl-key']: + config['ssl-key'] = os.path.expanduser(config['ssl-key']) + + if 'repositories' not in config: + config['repositories'] = [] + + deserialized = [] + + for repo_config in config['repositories']: + + # Setup branch if missing + if 'branch' not in repo_config: + repo_config['branch'] = "master" + + # Setup remote if missing + if 'remote' not in repo_config: + repo_config['remote'] = "origin" + + # Setup deploy commands list if not present + if 'deploy_commands' not in repo_config: + repo_config['deploy_commands'] = [] + + # Check if any global pre deploy commands is specified + if 'global_deploy' in config and len(config['global_deploy']) > 0 and len(config['global_deploy'][0]) is not 0: + repo_config['deploy_commands'].insert(0, config['global_deploy'][0]) + + # Check if any repo specific deploy command is specified + if 'deploy' in repo_config: + repo_config['deploy_commands'].append(repo_config['deploy']) + + # Check if any global post deploy command is specified + if 'global_deploy' in config and len(config['global_deploy']) > 1 and len(config['global_deploy'][1]) is not 0: + repo_config['deploy_commands'].append(config['global_deploy'][1]) + + # If a repository is configured with embedded credentials, we create an alternate URL + # without these credentials that cen be used when comparing the URL with URLs referenced + # in incoming web hook requests. + if 'url' in repo_config: + regexp = re.search(r"^(https?://)([^@]+)@(.+)$", repo_config['url']) + if regexp: + repo_config['url_without_usernme'] = regexp.group(1) + regexp.group(3) + + # Translate any ~ in the path into /home/ + if 'path' in repo_config: + repo_config['path'] = os.path.expanduser(repo_config['path']) + + # Support for legacy config format + if 'filters' in repo_config: + repo_config['payload-filter'] = repo_config['filters'] + del repo_config['filters'] + + if 'payload-filter' not in repo_config: + repo_config['payload-filter'] = [] + + if 'header-filter' not in repo_config: + repo_config['header-filter'] = {} + + # Rewrite some legacy filter config syntax + for filter in repo_config['payload-filter']: + + # Legacy config syntax? + if ('kind' in filter and filter['kind'] == 'pull-request-handler') or ('type' in filter and filter['type'] == 'pull-request-filter'): + + # Reset legacy values + filter['kind'] = None + filter['type'] = None + + if 'ref' in filter: + filter['pull_request.base.ref'] = filter['ref'] + filter['ref'] = None + + filter['pull_request'] = True + + project = Project(repo_config) + deserialized.append(project) + + config['repositories'] = deserialized + + return config + + +def get_repo_config_from_environment(): + """Look for repository config in any defined environment variables. If + found, import to main config.""" + import logging + import os + + if 'GAD_REPO_URL' not in os.environ: + return + + logger = logging.getLogger() + + repo_config = { + 'url': os.environ['GAD_REPO_URL'] + } + + logger.info("Added configuration for '%s' found in environment variables" % os.environ['GAD_REPO_URL']) + + if 'GAD_REPO_BRANCH' in os.environ: + repo_config['branch'] = os.environ['GAD_REPO_BRANCH'] + + if 'GAD_REPO_REMOTE' in os.environ: + repo_config['remote'] = os.environ['GAD_REPO_REMOTE'] + + if 'GAD_REPO_PATH' in os.environ: + repo_config['path'] = os.environ['GAD_REPO_PATH'] + + if 'GAD_REPO_DEPLOY' in os.environ: + repo_config['deploy'] = os.environ['GAD_REPO_DEPLOY'] + + return repo_config + + +def get_config_file_path(env_config, argv_config, search_target): + import os + + # Config file path provided in argument vector? + if 'config' in argv_config and argv_config['config']: + config_file_path = os.path.realpath(argv_config['config']) + + # Config file path provided in environment variable? + elif 'config' in env_config and env_config['config']: + config_file_path = os.path.realpath(env_config['config']) + + # Search file system + else: + + # Directories to scan for config files + target_directories = [ + os.getcwd(), # cwd + search_target # script path + ] + + config_file_path = find_config_file(target_directories) + + return config_file_path \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/data/git-auto-deploy.conf.json b/deploy/Git-Auto-Deploy/gitautodeploy/data/git-auto-deploy.conf.json new file mode 100755 index 0000000..5f8ebc2 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/data/git-auto-deploy.conf.json @@ -0,0 +1,64 @@ +{ + // HTTP server options + //"http-enabled": true, + //"http-host": "0.0.0.0", + //"http-port": 8001, + + // HTTPS server options + //"https-enabled": true, + //"https-host": "0.0.0.0", + //"https-port": 8002, + + // Web socket server options (used by web UI for real time updates) + //"wss-enabled": false, + //"wss-host": "0.0.0.0", + //"wss-port": 8003, + + // Web user interface options + //"web-ui-enabled": false, + //"web-ui-username": null, + //"web-ui-password": null, + //"web-ui-whitelist": ["127.0.0.1"], + + // TLS/SSL cert (necessary for HTTPS and web socket server to work) + //"ssl-key": null, // If specified, holds the private key + "ssl-cert": "/etc/git-auto-deploy/cert.pem", // Holds the public key or both the private and public keys + + // File to store a copy of the console output + "log-file": "/var/log/git-auto-deploy.log", + + // Record all log levels by default + //"log-level": "NOTSET", + + // Deploy commands that should be executed for all projects + //"global_deploy": [ + // "echo Deploy started!", + // "echo Deploy completed!" + //], + + // Project configs + "repositories": [ + { + "url": "https://github.com/olipo186/Git-Auto-Deploy.git", + "branch": "master", + "remote": "origin", + "path": "/var/lib/git-auto-deploy/Git-Auto-Deploy", + "deploy": "echo deploying" + }, + { + "url": "https://github.com/github/gitignore", + "path": "/var/lib/git-auto-deploy/gitignore" + } +// ,{ +// "url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy", +// "deploy": "echo deploying after pull request", +// "filters": [ +// { +// "type": "pull-request-filter", +// "action": "closed", +// "ref": "testing-branch" +// } +// ] +// } + ] +} \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/events.py b/deploy/Git-Auto-Deploy/gitautodeploy/events.py new file mode 100644 index 0000000..ab3cdec --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/events.py @@ -0,0 +1,187 @@ +class SystemEvent(object): + + def __init__(self, name=None): + import logging + + self.logger = logging.getLogger() + self.hub = None + self.messages = [] + self.name = name + self.id = None + self.waiting = None + self.success = None + + def __repr__(self): + if self.id: + return "" % self.id + else: + return "" + + def dict_repr(self): + from time import time + return { + "id": self.id, + "type": type(self).__name__, + "timestamp": time(), + "messages": self.messages, + "waiting": self.waiting, + "success": self.success + } + + def register_hub(self, hub): + self.hub = hub + + def register_message(self, message, level="INFO"): + self.messages.append(message) + self.hub.notify_observers(type="event-updated", event=self.dict_repr()) + + def set_id(self, id): + self.id = id + + def get_id(self): + return self.id + + def set_waiting(self, value): + self.waiting = value + self.hub.notify_observers(type="event-updated", event=self.dict_repr()) + + def set_success(self, value): + self.success = value + self.hub.notify_observers(type="event-updated", event=self.dict_repr()) + self.hub.notify_observers(type="event-success", id=self.id, success=value) + + def log_debug(self, message): + self.logger.debug(message) + self.register_message(message, "DEBUG") + + def log_info(self, message): + self.logger.info(message) + self.register_message(message, "INFO") + + def log_warning(self, message): + self.logger.warning(message) + self.register_message(message, "WARNING") + + def log_error(self, message): + self.logger.error(message) + self.register_message(message, "ERROR") + + def log_critical(self, message): + self.logger.critical(message) + self.register_message(message, "CRITICAL") + + #def update(self): + # self.hub.notify_observers(type="event-updated", event=self.dict_repr()) + + +class WebhookAction(SystemEvent): + """Represents a webhook request event and keeps a copy of all incoming and outgoing data for monitoring purposes.""" + + def __init__(self, client_address, request_headers, request_body): + self.client_address = client_address + self.request_headers = request_headers + self.request_body = request_body + super(WebhookAction, self).__init__() + + def __repr__(self): + return "" + + def dict_repr(self): + data = super(WebhookAction, self).dict_repr() + data['client-address'] = self.client_address[0] + data['client-port'] = self.client_address[1] + data['request-headers'] = self.request_headers + data['request-body'] = self.request_body + return data + + +class DeployEvent(SystemEvent): + + def __init__(self, project): + self.project = project + super(DeployEvent, self).__init__() + + def __repr__(self): + return "" + + def dict_repr(self): + data = super(DeployEvent, self).dict_repr() + data['name'] = self.project.get_name() + return data + + +class StartupEvent(SystemEvent): + + def __init__(self, http_address=None, http_port=None, ws_address=None, ws_port=None): + self.http_address = http_address + self.http_port = http_port + self.http_started = None + self.ws_address = ws_address + self.ws_port = ws_port + self.ws_started = None + self.waiting = True + super(StartupEvent, self).__init__() + + def __repr__(self): + return "" + + def dict_repr(self): + data = super(StartupEvent, self).dict_repr() + data['http-address'] = self.http_address + data['http-port'] = self.http_port + data['http-started'] = self.http_started + data['ws-address'] = self.ws_address + data['ws-port'] = self.ws_port + data['ws-started'] = self.ws_started + return data + + def set_http_started(self, value): + self.http_started = value + self.hub.notify_observers(type="event-updated", event=self.dict_repr()) + self.validate_success() + + def set_ws_started(self, value): + self.ws_started = value + self.hub.notify_observers(type="event-updated", event=self.dict_repr()) + self.validate_success() + + def validate_success(self): + if self.http_started is not False and self.ws_started is not False: + self.set_waiting(False) + self.set_success(True) + + +class EventStore(object): + + def __init__(self): + self.actions = [] + self.observers = [] + self.next_id = 0 + + def register_observer(self, observer): + self.observers.append(observer) + + def unregister_observer(self, observer): + if observer in self.observers: + self.observers.remove(observer) + + def notify_observers(self, *args, **kwargs): + for observer in self.observers: + observer.update(*args, **kwargs) + + def register_action(self, event): + event.set_id(self.next_id) + event.register_hub(self) + self.next_id = self.next_id + 1 + self.actions.append(event) + self.notify_observers(type="new-event", event=event.dict_repr()) + + # Store max 100 actions + if len(self.actions) > 100: + self.actions.pop(0) + + def dict_repr(self): + action_repr = [] + for action in self.actions: + action_repr.append(action.dict_repr()) + return action_repr diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/gitautodeploy.py b/deploy/Git-Auto-Deploy/gitautodeploy/gitautodeploy.py new file mode 100644 index 0000000..663b036 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/gitautodeploy.py @@ -0,0 +1,679 @@ +if __name__ == '__main__': + import sys + print("Critical - GAD must be started as a python module, for example using python -m gitautodeploy") + sys.exit() + + +class LogInterface(object): + """Interface that functions as a stdout and stderr handler and directs the + output to the logging module, which in turn will output to either console, + file or both.""" + + def __init__(self, level=None): + import logging + self.level = (level if level else logging.getLogger().info) + + def write(self, msg): + for line in msg.strip().split("\n"): + self.level(line) + + def flush(self): + pass + + +from .wsserver import WebSocketClientHandlerFactory +from .httpserver import WebhookRequestHandlerFactory + + +class GitAutoDeploy(object): + _instance = None + _http_server = None + _https_server = None + _https_server_unwrapped_socket = None + _config = {} + _server_status = {} + _pid = None + _event_store = None + _default_stdout = None + _default_stderr = None + _startup_event = None + _ws_clients = [] + _http_port = None + + def __new__(cls, *args, **kwargs): + """Overload constructor to enable singleton access""" + if not cls._instance: + cls._instance = super(GitAutoDeploy, cls).__new__( + cls, *args, **kwargs) + return cls._instance + + def __init__(self): + from .events import EventStore, StartupEvent + + # Setup an event store instance that can keep a global record of events + self._event_store = EventStore() + self._event_store.register_observer(self) + + # Create a startup event that can hold status and any error messages + # from the startup process + self._startup_event = StartupEvent() + self._event_store.register_action(self._startup_event) + + def clone_all_repos(self): + """Iterates over all configured repositories and clones them to their + configured paths.""" + import os + import re + import logging + from .wrappers import GitWrapper + logger = logging.getLogger() + + if 'repositories' not in self._config: + return + + # Iterate over all configured repositories + for repo_config in self._config['repositories']: + + # Only clone repositories with a configured path + if 'url' not in repo_config: + logger.critical("Repository has no configured URL") + self.exit() + return + + # Only clone repositories with a configured path + if 'path' not in repo_config: + logger.debug("Repository %s will not be cloned (no path configured)" % repo_config['url']) + continue + + if os.path.isdir(repo_config['path']) and os.path.isdir(repo_config['path']+'/.git'): + GitWrapper.init(repo_config) + else: + GitWrapper.clone(repo_config) + + def ssh_key_scan(self): + import re + import logging + from .wrappers import ProcessWrapper + logger = logging.getLogger() + + for repository in self._config['repositories']: + + if 'url' not in repository: + continue + + logger.info("Scanning repository: %s" % repository['url']) + m = re.match('[^\@]+\@([^\:\/]+)(:(\d+))?', repository['url']) + + if m is not None: + host = m.group(1) + port = m.group(3) + port_arg = '' if port is None else ('-p %s ' % port) + cmd = 'ssh-keyscan %s%s >> $HOME/.ssh/known_hosts' % (port_arg, host) + ProcessWrapper().call([cmd], shell=True) + + else: + logger.error('Could not find regexp match in path: %s' % repository['url']) + + def create_pid_file(self): + import os + + with open(self._config['pid-file'], 'w') as f: + f.write(str(os.getpid())) + + def read_pid_file(self): + with open(self._config['pid-file'], 'r') as f: + return f.readlines() + + def remove_pid_file(self): + import os + import errno + if 'pid-file' in self._config and self._config['pid-file']: + try: + os.remove(self._config['pid-file']) + except OSError as e: + # errno.ENOENT = no such file or directory + if e.errno != errno.ENOENT: + raise + + @staticmethod + def create_daemon(): + import os + + try: + # Spawn first child. Returns 0 in the child and pid in the parent. + pid = os.fork() + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + # First child + if pid == 0: + os.setsid() + + try: + # Spawn second child + pid = os.fork() + + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if pid == 0: + os.umask(0) + else: + # Kill first child + os._exit(0) + else: + # Kill parent of first child + os._exit(0) + + return 0 + + def update(self, *args, **kwargs): + import json + data = json.dumps(kwargs).encode('utf-8') + for client in self._ws_clients: + client.sendMessage(data) + + def get_log_formatter(self): + import logging + return logging.Formatter("%(asctime)s [%(levelname)-5.5s] %(message)s") + + def setup_console_logger(self): + import logging + + # Set up logging + logger = logging.getLogger() + + consoleHandler = logging.StreamHandler() + consoleHandler.setFormatter(self.get_log_formatter()) + + # Check if a stream handler is already present (will be if GAD is started by test script) + handler_present = False + for handler in logger.handlers: + if isinstance(handler, type(consoleHandler)): + handler_present = True + break + + if not handler_present: + logger.addHandler(consoleHandler) + + def setup(self, config): + """Setup an instance of GAD based on the provided config object.""" + import sys + import socket + import os + import logging + import base64 + from .lock import Lock + import getpass + + # This solves https://github.com/olipo186/Git-Auto-Deploy/issues/118 + try: + from logging import NullHandler + except ImportError: + from logging import Handler + + class NullHandler(Handler): + def emit(self, record): + pass + + # Attatch config values to this instance + self._config = config + + # Set up logging + logger = logging.getLogger() + logFormatter = self.get_log_formatter() + + # Enable console output? + if ('quiet' in self._config and self._config['quiet']) or ('daemon-mode' in self._config and self._config['daemon-mode']): + + # Add a default null handler that suppresses any console output + logger.addHandler(NullHandler()) + + else: + + # Set up console logger if not already present + self.setup_console_logger() + + # Set logging level + if 'log-level' in self._config: + level = logging.getLevelName(self._config['log-level']) + logger.setLevel(level) + + if 'log-file' in self._config and self._config['log-file']: + # Translate any ~ in the path into /home/ + fileHandler = logging.FileHandler(self._config['log-file']) + fileHandler.setFormatter(logFormatter) + logger.addHandler(fileHandler) + + # Display a warning when trying to run as root + if not self._config['allow-root-user'] and getpass.getuser() == 'root': + logger.critical("Refusing to start as root. This application shouldn't run as a privileged used. Please run it as a different user. To disregard this warning and start anyway, set the config option \"allow-root-user\" to true, or use the command line argument --allow-root-user") + sys.exit() + + if 'ssh-keyscan' in self._config and self._config['ssh-keyscan']: + self._startup_event.log_info('Scanning repository hosts for ssh keys...') + self.ssh_key_scan() + + # Clone all repos once initially + self.clone_all_repos() + + # Set default stdout and stderr to our logging interface (that writes + # to file and console depending on user preference) + if 'intercept-stdout' in self._config and self._config['intercept-stdout']: + self._default_stdout = sys.stdout + self._default_stderr = sys.stderr + sys.stdout = LogInterface(logger.info) + sys.stderr = LogInterface(logger.error) + + if 'daemon-mode' in self._config and self._config['daemon-mode']: + self._startup_event.log_info('Starting Git Auto Deploy in daemon mode') + GitAutoDeploy.create_daemon() + + self._pid = os.getpid() + self.create_pid_file() + + # Generate auth key to protect the web socket server + self._server_status['auth-key'] = base64.b64encode(os.urandom(32)) + + # Clear any existing lock files, with no regard to possible ongoing processes + for repo_config in self._config['repositories']: + + # Do we have a physical repository? + if 'path' in repo_config: + Lock(os.path.join(repo_config['path'], 'status_running')).clear() + Lock(os.path.join(repo_config['path'], 'status_waiting')).clear() + + #if 'daemon-mode' not in self._config or not self._config['daemon-mode']: + # self._startup_event.log_info('Git Auto Deploy started') + + def serve_http(self, serve_forever=True): + """Starts a HTTP server that listens for webhook requests and serves the web ui.""" + import sys + import socket + import os + from .events import SystemEvent + + try: + from BaseHTTPServer import HTTPServer + except ImportError as e: + from http.server import HTTPServer + + if not self._config['http-enabled']: + return + + # Setup + try: + + # Create web hook request handler class + WebhookRequestHandler = WebhookRequestHandlerFactory(self._config, self._event_store, self._server_status, is_https=False) + + # Create HTTP server + self._http_server = HTTPServer((self._config['http-host'], + self._config['http-port']), + WebhookRequestHandler) + + # Setup SSL for HTTP server + sa = self._http_server.socket.getsockname() + self._http_port = sa[1] + self._server_status['http-uri'] = "http://%s:%s" % (self._config['http-host'], sa[1]) + self._startup_event.log_info("Listening for connections on %s" % self._server_status['http-uri']) + self._startup_event.http_address = sa[0] + self._startup_event.http_port = sa[1] + self._startup_event.set_http_started(True) + + except socket.error as e: + self._startup_event.log_critical("Unable to start HTTP server: %s" % e) + return + + if not serve_forever: + return + + # Run forever + try: + self._http_server.serve_forever() + + except socket.error as e: + event = SystemEvent() + self._event_store.register_action(event) + event.log_critical("Error on socket: %s" % e) + sys.exit(1) + + except KeyboardInterrupt as e: + event = SystemEvent() + self._event_store.register_action(event) + event.log_info('Requested close by keyboard interrupt signal') + self.stop() + self.exit() + + event = SystemEvent() + self._event_store.register_action(event) + event.log_info('HTTP server did quit') + + def serve_https(self): + """Starts a HTTPS server that listens for webhook requests and serves the web ui.""" + import sys + import socket + import os + import ssl + from .events import SystemEvent + + try: + from BaseHTTPServer import HTTPServer + except ImportError as e: + from http.server import HTTPServer + + if not self._config['https-enabled']: + return + + if not os.path.isfile(self._config['ssl-cert']): + self._startup_event.log_critical("Unable to activate SSL: File does not exist: %s" % self._config['ssl-cert']) + return + + # Setup + try: + + # Create web hook request handler class + WebhookRequestHandler = WebhookRequestHandlerFactory(self._config, self._event_store, self._server_status, is_https=True) + + # Create HTTP server + self._https_server = HTTPServer((self._config['https-host'], + self._config['https-port']), + WebhookRequestHandler) + + # Setup SSL for HTTP server + self._https_server_unwrapped_socket = self._https_server.socket + self._https_server.socket = ssl.wrap_socket(self._https_server.socket, + keyfile=self._config['ssl-key'], + certfile=self._config['ssl-cert'], + server_side=True) + + sa = self._https_server.socket.getsockname() + self._http_port = sa[1] + self._server_status['https-uri'] = "https://%s:%s" % (self._config['https-host'], sa[1]) + + self._startup_event.log_info("Listening for connections on %s" % self._server_status['https-uri']) + self._startup_event.http_address = sa[0] + self._startup_event.http_port = sa[1] + self._startup_event.set_http_started(True) + + except socket.error as e: + self._startup_event.log_critical("Unable to start HTTPS server: %s" % e) + return + + # Run forever + try: + self._https_server.serve_forever() + + except socket.error as e: + event = SystemEvent() + self._event_store.register_action(event) + event.log_critical("Error on socket: %s" % e) + sys.exit(1) + + except KeyboardInterrupt as e: + event = SystemEvent() + self._event_store.register_action(event) + event.log_info('Requested close by keyboard interrupt signal') + self.stop() + self.exit() + + event = SystemEvent() + self._event_store.register_action(event) + event.log_info('HTTPS server did quit') + + def serve_wss(self): + """Start a web socket server over SSL, used by the web UI to get notifications about updates.""" + import os + from .events import SystemEvent + + # Start a web socket server if the web UI is enabled + if not self._config['web-ui-enabled']: + return + + if not self._config['wss-enabled']: + return + + if not os.path.isfile(self._config['ssl-cert']): + self._startup_event.log_critical("Unable to activate SSL: File does not exist: %s" % self._config['ssl-cert']) + return + + try: + import os + from autobahn.websocket import WebSocketServerProtocol, WebSocketServerFactory + from twisted.internet import reactor, ssl + from twisted.internet.error import BindError + + # Create a WebSocketClientHandler instance + WebSocketClientHandler = WebSocketClientHandlerFactory(self._config, self._ws_clients, self._event_store, self._server_status) + + uri = u"ws://%s:%s" % (self._config['wss-host'], self._config['wss-port']) + factory = WebSocketServerFactory(uri) + factory.protocol = WebSocketClientHandler + # factory.setProtocolOptions(maxConnections=2) + + # note to self: if using putChild, the child must be bytes... + if self._config['ssl-key'] and self._config['ssl-cert']: + contextFactory = ssl.DefaultOpenSSLContextFactory(privateKeyFileName=self._config['ssl-key'], certificateFileName=self._config['ssl-cert']) + else: + contextFactory = ssl.DefaultOpenSSLContextFactory(privateKeyFileName=self._config['ssl-cert'], certificateFileName=self._config['ssl-cert']) + + + self._ws_server_port = reactor.listenSSL(self._config['wss-port'], factory, contextFactory) + # self._ws_server_port = reactor.listenTCP(self._config['wss-port'], factory) + + self._server_status['wss-uri'] = "wss://%s:%s" % (self._config['wss-host'], self._config['wss-port']) + + self._startup_event.log_info("Listening for connections on %s" % self._server_status['wss-uri']) + self._startup_event.ws_address = self._config['wss-host'] + self._startup_event.ws_port = self._config['wss-port'] + self._startup_event.set_ws_started(True) + + # Serve forever (until reactor.stop()) + reactor.run(installSignalHandlers=False) + + except BindError as e: + self._startup_event.log_critical("Unable to start web socket server: %s" % e) + + except ImportError: + self._startup_event.log_error("Unable to start web socket server due to missing dependency.") + + event = SystemEvent() + self._event_store.register_action(event) + event.log_info('WSS server did quit') + + def serve_forever(self): + """Start HTTP and web socket servers.""" + import sys + import socket + import logging + import os + from .events import SystemEvent + import threading + + try: + from autobahn.websocket import WebSocketServerProtocol, WebSocketServerFactory + from twisted.internet import reactor + + # Given that the nessecary dependencies are present, notify the + # event that we expect the web socket server to be started + self._startup_event.ws_started = False + except ImportError: + pass + + # Notify the event that we expect the http server to be started + self._startup_event.http_started = False + + # Add script dir to sys path, allowing us to import sub modules even after changing cwd + sys.path.insert(1, os.path.dirname(os.path.realpath(__file__))) + + # Set CWD to public www folder. This makes the http server serve files from the wwwroot directory. + wwwroot = os.path.join(os.path.dirname(os.path.realpath(__file__)), "wwwroot") + os.chdir(wwwroot) + + threads = [ + # HTTP server + threading.Thread(target=self.serve_http), + + # HTTPS server + threading.Thread(target=self.serve_https), + + # Web socket SSL server + threading.Thread(target=self.serve_wss) + ] + + # Start all threads + for thread in threads: + thread.start() + + # Wait for each thread to finish + for thread in threads: + + # Wait for thread to finish without blocking main thread + while thread.is_alive(): + thread.join(5) + + def signal_handler(self, signum, frame): + from .events import SystemEvent + self.stop() + + event = SystemEvent() + self._event_store.register_action(event) + + # Reload configuration on SIGHUP events (conventional for daemon processes) + if signum == 1: + self.setup(self._config) + self.serve_forever() + return + + # Keyboard interrupt signal + elif signum == 2: + event.log_info('Recieved keyboard interrupt signal (%s) from the OS, shutting down.' % signum) + + else: + event.log_info('Recieved signal (%s) from the OS, shutting down.' % signum) + + self.exit() + + def stop(self): + """Stop all running TCP servers (HTTP and web socket servers)""" + + # Stop HTTP server if running + if self._http_server is not None: + + # Shut down the underlying TCP server + self._http_server.shutdown() + + # Close the socket + self._http_server.socket.close() + + # Stop HTTPS server if running + if self._https_server is not None: + + # Shut down the underlying TCP server + self._https_server.shutdown() + + # Close the socket + self._https_server.socket.close() + + if self._https_server_unwrapped_socket is not None: + + self._https_server_unwrapped_socket.close() + + # Stop web socket server if running + try: + from twisted.internet import reactor + reactor.callFromThread(reactor.stop) + except ImportError: + pass + + def exit(self): + import sys + import logging + logger = logging.getLogger() + logger.info('Goodbye') + + # Delete PID file + self.remove_pid_file() + + # Restore stdin and stdout + if 'intercept-stdout' in self._config and self._config['intercept-stdout']: + sys.stdout = self._default_stdout + sys.stderr = self._default_stderr + + +def main(): + import signal + from gitautodeploy import GitAutoDeploy + from cli.config import get_config_defaults, get_config_from_environment + from cli.config import get_config_from_argv, find_config_file + from cli.config import get_config_from_file, get_repo_config_from_environment + from cli.config import init_config, get_config_file_path, rename_legacy_attribute_names + from cli.config import ConfigFileNotFoundException, ConfigFileInvalidException + import logging + import sys + import os + + logger = logging.getLogger() + + app = GitAutoDeploy() + + if hasattr(signal, 'SIGHUP'): + signal.signal(signal.SIGHUP, app.signal_handler) + if hasattr(signal, 'SIGINT'): + signal.signal(signal.SIGINT, app.signal_handler) + if hasattr(signal, 'SIGABRT'): + signal.signal(signal.SIGABRT, app.signal_handler) + if hasattr(signal, 'SIGPIPE') and hasattr(signal, 'SIG_IGN'): + signal.signal(signal.SIGPIPE, signal.SIG_IGN) + + # Get default config values + config = get_config_defaults() + + # Get config values from environment variables and commadn line arguments + environment_config = get_config_from_environment() + argv_config = get_config_from_argv(sys.argv[1:]) + + # Merge config values from environment variables + config.update(environment_config) + + search_target = os.path.dirname(os.path.realpath(__file__)) + config_file_path = get_config_file_path(environment_config, argv_config, search_target) + + # Config file path provided or found? + if config_file_path: + + try: + file_config = get_config_from_file(config_file_path) + except ConfigFileNotFoundException as e: + app.setup_console_logger() + logger.critical("No config file not found at '%s'" % e) + return + except ConfigFileInvalidException as e: + app.setup_console_logger() + logger.critical("Unable to read config file due to invalid JSON format in '%s'" % e) + return + + # Merge config values from config file (overrides environment variables) + config.update(file_config) + + # Merge config value from command line (overrides environment variables and config file) + config.update(argv_config) + + # Rename legacy config option names + config = rename_legacy_attribute_names(config) + + # Extend config data with any repository defined by environment variables + repo_config = get_repo_config_from_environment() + + if repo_config: + + if not 'repositories' in config: + config['repositories'] = [] + + config['repositories'].append(repo_config) + + # Initialize config by expanding with missing values + init_config(config) + + app.setup(config) + app.serve_forever() diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/httpserver.py b/deploy/Git-Auto-Deploy/gitautodeploy/httpserver.py new file mode 100644 index 0000000..83e0a1a --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/httpserver.py @@ -0,0 +1,346 @@ +from __future__ import absolute_import +from .events import WebhookAction +from .parsers import get_service_handler + + +def WebhookRequestHandlerFactory(config, event_store, server_status, is_https=False): + """Factory method for webhook request handler class""" + try: + from SimpleHTTPServer import SimpleHTTPRequestHandler + except ImportError as e: + from http.server import SimpleHTTPRequestHandler + + class WebhookRequestHandler(SimpleHTTPRequestHandler, object): + """Extends the BaseHTTPRequestHandler class and handles the incoming + HTTP requests.""" + + def __init__(self, *args, **kwargs): + self._config = config + self._event_store = event_store + self._server_status = server_status + self._is_https = is_https + super(WebhookRequestHandler, self).__init__(*args, **kwargs) + + def end_headers(self): + self.send_header('Access-Control-Allow-Origin', '*') + SimpleHTTPRequestHandler.end_headers(self) + + def do_HEAD(self): + + # Web UI needs to be enabled + if not self.validate_web_ui_enabled(): + return + + # Web UI might require HTTPS + if not self.validate_web_ui_https(): + return + + # Client needs to be whitelisted + if not self.validate_web_ui_whitelist(): + return + + # Client needs to authenticate + if not self.validate_web_ui_basic_auth(): + return + + return SimpleHTTPRequestHandler.do_HEAD(self) + + def do_GET(self): + + # Web UI needs to be enabled + if not self.validate_web_ui_enabled(): + return + + # Web UI might require HTTPS + if not self.validate_web_ui_https(): + return + + # Client needs to be whitelisted + if not self.validate_web_ui_whitelist(): + return + + # Client needs to authenticate + if not self.validate_web_ui_basic_auth(): + return + + # Handle status API call + if self.path == "/api/status": + self.handle_status_api() + return + + # Serve static file + return SimpleHTTPRequestHandler.do_GET(self) + + def handle_status_api(self): + import json + from os import urandom + from base64 import b64encode + + data = { + 'events': self._event_store.dict_repr(), + 'auth-key': self._server_status['auth-key'] + } + + data.update(self.get_server_status()) + + self.send_response(200, 'OK') + self.send_header('Content-type', 'application/json') + self.end_headers() + self.wfile.write(json.dumps(data).encode('utf-8')) + + def do_POST(self): + """Invoked on incoming POST requests""" + from threading import Timer + import logging + import json + import threading + from urlparse import parse_qs + + logger = logging.getLogger() + + content_length = int(self.headers.get('content-length')) + request_body = self.rfile.read(content_length).decode('utf-8') + + # Extract request headers and make all keys to lowercase (makes them easier to compare) + request_headers = dict(self.headers) + request_headers = dict((k.lower(), v) for k, v in request_headers.items()) + + action = WebhookAction(self.client_address, request_headers, request_body) + self._event_store.register_action(action) + action.set_waiting(True) + + action.log_info('Incoming request from %s:%s' % (self.client_address[0], self.client_address[1])) + + # Payloads from GitHub can be delivered as form data. Test the request for this pattern and extract json payload + if request_headers['content-type'] == 'application/x-www-form-urlencoded': + res = parse_qs(request_body.decode('utf-8')) + if 'payload' in res and len(res['payload']) == 1: + request_body = res['payload'][0] + + # Test case debug data + test_case = { + 'headers': dict(self.headers), + 'payload': json.loads(request_body), + 'config': {}, + 'expected': {'status': 200, 'data': [{'deploy': 0}]} + } + + try: + + # Will raise a ValueError exception if it fails + ServiceRequestHandler = get_service_handler(request_headers, request_body, action) + + # Unable to identify the source of the request + if not ServiceRequestHandler: + self.send_error(400, 'Unrecognized service') + test_case['expected']['status'] = 400 + action.log_error("Unable to find appropriate handler for request. The source service is not supported") + action.set_waiting(False) + action.set_success(False) + return + + service_handler = ServiceRequestHandler(self._config) + + action.log_info("Handling the request with %s" % ServiceRequestHandler.__name__) + + # Could be GitHubParser, GitLabParser or other + projects = service_handler.get_matching_projects(request_headers, request_body, action) + + action.log_info("%s candidates matches the request" % len(projects)) + + # request_filter = WebhookRequestFilter() + + if len(projects) == 0: + self.send_error(400, 'Bad request') + test_case['expected']['status'] = 400 + action.log_error("No matching projects") + action.set_waiting(False) + action.set_success(False) + return + + # Apply filters + matching_projects = [] + for project in projects: + if project.apply_filters(request_headers, request_body, action): + matching_projects.append(project) + + # Only keep projects that matches + projects = matching_projects + + action.log_info("%s candidates matches after applying filters" % len(projects)) + + if not service_handler.validate_request(request_headers, request_body, projects, action): + self.send_error(400, 'Bad request') + test_case['expected']['status'] = 400 + action.log_warning("Request was rejected due to a secret token mismatch") + action.set_waiting(False) + action.set_success(False) + return + + test_case['expected']['status'] = 200 + + self.send_response(200, 'OK') + self.send_header('Content-type', 'text/plain') + self.end_headers() + + if len(projects) == 0: + action.set_waiting(False) + action.set_success(False) + return + + action.log_info("Proceeding with %s candidates" % len(projects)) + action.set_waiting(False) + action.set_success(True) + + for project in projects: + + # Schedule the execution of the webhook (git pull and trigger deploy etc) + thread = threading.Thread(target=project.execute_webhook, args=[self._event_store]) + thread.start() + + # Add additional test case data + test_case['config'] = { + 'url': 'url' in project and project['url'], + 'branch': 'branch' in project and project['branch'], + 'remote': 'remote' in project and project['remote'], + 'deploy': 'echo test!' + } + + except ValueError as e: + self.send_error(400, 'Unprocessable request') + action.log_warning('Unable to process incoming request from %s:%s' % (self.client_address[0], self.client_address[1])) + test_case['expected']['status'] = 400 + action.set_waiting(False) + action.set_success(False) + return + + except Exception as e: + self.send_error(500, 'Unable to process request') + test_case['expected']['status'] = 500 + action.log_warning("Unable to process request") + action.set_waiting(False) + action.set_success(False) + + raise e + + finally: + + # Save the request as a test case + if 'log-test-case' in self._config and self._config['log-test-case']: + self.save_test_case(test_case) + + def log_message(self, format, *args): + """Overloads the default message logging method to allow messages to + go through our custom logger instead.""" + import logging + logger = logging.getLogger() + logger.info("%s - %s" % (self.client_address[0], format%args)) + + def save_test_case(self, test_case): + """Log request information in a way it can be used as a test case.""" + import time + import json + import os + + # Mask some header values + masked_headers = ['x-github-delivery', 'x-hub-signature'] + for key in test_case['headers']: + if key in masked_headers: + test_case['headers'][key] = 'xxx' + + target = '%s-%s.tc.json' % (self.client_address[0], time.strftime("%Y%m%d%H%M%S")) + if 'log-test-case-dir' in self._config and self._config['log-test-case-dir']: + target = os.path.join(self._config['log-test-case-dir'], target) + + file = open(target, 'w') + file.write(json.dumps(test_case, sort_keys=True, indent=4)) + file.close() + + def get_server_status(self): + """Generate a copy of the server status object that contains the public IP or hostname.""" + + server_status = {} + for item in self._server_status.items(): + key, value = item + public_host = self.headers.get('host').split(':')[0] + + if key == 'http-uri': + server_status[key] = value.replace(self._config['http-host'], public_host) + + if key == 'https-uri': + server_status[key] = value.replace(self._config['https-host'], public_host) + + if key == 'wss-uri': + server_status[key] = value.replace(self._config['wss-host'], public_host) + + return server_status + + def validate_web_ui_enabled(self): + """Verify that the Web UI is enabled""" + + if self._config['web-ui-enabled']: + return True + + self.send_error(403, "Web UI is not enabled") + return False + + def validate_web_ui_https(self): + """Verify that the request is made over HTTPS""" + + if self._is_https: + return True + + if not self._config['web-ui-require-https']: + return True + + # Attempt to redirect the request to HTTPS + server_status = self.get_server_status() + if 'https-uri' in server_status: + self.send_response(307) + self.send_header('Location', '%s%s' % (server_status['https-uri'], self.path)) + self.end_headers() + return False + + self.send_error(403, "Web UI is only accessible through HTTPS") + return False + + def validate_web_ui_whitelist(self): + """Verify that the client address is whitelisted""" + + # Allow all if whitelist is empty + if len(self._config['web-ui-whitelist']) == 0: + return True + + # Verify that client IP is whitelisted + if self.client_address[0] in self._config['web-ui-whitelist']: + return True + + self.send_error(403, "%s is not allowed access" % self.client_address[0]) + return False + + def validate_web_ui_basic_auth(self): + """Authenticate the user""" + import base64 + + if not self._config['web-ui-auth-enabled']: + return True + + # Verify that a username and password is specified in the config + if self._config['web-ui-username'] is None or self._config['web-ui-password'] is None: + self.send_error(403, "Authentication credentials missing in config") + return False + + # Verify that the provided username and password matches the ones in the config + key = base64.b64encode("%s:%s" % (self._config['web-ui-username'], self._config['web-ui-password'])) + if self.headers.getheader('Authorization') == 'Basic ' + key: + return True + + # Let the client know that authentication is required + self.send_response(401) + self.send_header('WWW-Authenticate', 'Basic realm=\"GAD\"') + self.send_header('Content-type', 'text/html') + self.end_headers() + self.wfile.write('Not authenticated') + return False + + return WebhookRequestHandler diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/lock.py b/deploy/Git-Auto-Deploy/gitautodeploy/lock.py new file mode 100644 index 0000000..126496b --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/lock.py @@ -0,0 +1,54 @@ + +class Lock(): + """Simple implementation of a mutex lock using the file systems. Works on + *nix systems.""" + + path = None + lock = None + + def __init__(self, path): + try: + from lockfile import LockFile + except ImportError: + from lockfile import FileLock + # Different naming in older versions of lockfile + LockFile = FileLock + + self.path = path + self.lock = LockFile(path) + + def obtain(self): + import os + import logging + from lockfile import AlreadyLocked + logger = logging.getLogger() + + try: + self.lock.acquire(0) + logger.debug("Successfully obtained lock: %s" % self.path) + except AlreadyLocked: + return False + + return True + + def release(self): + import os + import logging + logger = logging.getLogger() + + if not self.has_lock(): + raise Exception("Unable to release lock that is owned by another process") + + self.lock.release() + logger.debug("Successfully released lock: %s" % self.path) + + def has_lock(self): + return self.lock.i_am_locking() + + def clear(self): + import os + import logging + logger = logging.getLogger() + + self.lock.break_lock() + logger.debug("Successfully cleared lock: %s" % self.path) diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/models/__init__.py b/deploy/Git-Auto-Deploy/gitautodeploy/models/__init__.py new file mode 100644 index 0000000..e2ebdf8 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/models/__init__.py @@ -0,0 +1 @@ +from .project import * \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/models/project.py b/deploy/Git-Auto-Deploy/gitautodeploy/models/project.py new file mode 100644 index 0000000..954da99 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/models/project.py @@ -0,0 +1,210 @@ +import collections +from ..wrappers import GitWrapper +from ..lock import Lock +from ..wrappers import GitWrapper +from ..events import DeployEvent + + +class Project(collections.MutableMapping): + + """A dictionary that applies an arbitrary key-altering + function before accessing the keys""" + + def __init__(self, *args, **kwargs): + self.store = dict() + self.update(dict(*args, **kwargs)) # use the free update to set keys + + def __getitem__(self, key): + return self.store[self.__keytransform__(key)] + + def __setitem__(self, key, value): + self.store[self.__keytransform__(key)] = value + + def __delitem__(self, key): + del self.store[self.__keytransform__(key)] + + def __iter__(self): + return iter(self.store) + + def __len__(self): + return len(self.store) + + def __keytransform__(self, key): + return key + + def get_name(self): + return self['url'].split('/')[-1].split('.git')[0] + + def passes_payload_filter(self, payload, action): + + # At least one filter must match + for filter in self['payload-filter']: + + # All options specified in the filter must match + for filter_key, filter_value in filter.items(): + + # Ignore filters with value None (let them pass) + if filter_value == None: + continue + + # Interpret dots in filter name as path notations + node_value = payload + for node_key in filter_key.split('.'): + + # If the path is not valid the filter does not match + if not node_key in node_value: + action.log_info("Filter '%s' does not match since the path is invalid" % (filter_key)) + + # Filter does not match, do not process this repo config + return False + + node_value = node_value[node_key] + + if filter_value == node_value: + continue + + # If the filter value is set to True. the filter + # will pass regardless of the actual value + if filter_value == True: + continue + + action.log_debug("Filter '%s' does not match ('%s' != '%s')" % (filter_key, filter_value, (str(node_value)[:75] + '..') if len(str(node_value)) > 75 else str(node_value))) + + # Filter does not match, do not process this repo config + return False + + # Filter does match, proceed + return True + + def passes_header_filter(self, request_headers): + + # At least one filter must match + for key in self['header-filter']: + + # Verify that the request has the required header attribute + if key.lower() not in request_headers: + return False + + # "True" indicates that any header value is accepted + if self['header-filter'][key] is True: + continue + + # Verify that the request has the required header value + if self['header-filter'][key] != request_headers[key.lower()]: + return False + + # Filter does match, proceed + return True + + def apply_filters(self, request_headers, request_body, action): + """Verify that the suggested repositories has matching settings and + issue git pull and/or deploy commands.""" + import os + import time + import json + + payload = json.loads(request_body) + + # Verify that all payload filters matches the request (if any payload filters are specified) + if 'payload-filter' in self and not self.passes_payload_filter(payload, action): + + # Filter does not match, do not process this repo config + return False + + # Verify that all header filters matches the request (if any header filters are specified) + if 'header-filter' in self and not self.passes_header_filter(request_headers): + + # Filter does not match, do not process this repo config + return False + + return True + + def execute_webhook(self, event_store): + """Verify that the suggested repositories has matching settings and + issue git pull and/or deploy commands.""" + import os + import time + import json + + event = DeployEvent(self) + event_store.register_action(event) + event.set_waiting(True) + event.log_info("Running deploy commands") + + # In case there is no path configured for the repository, no pull will + # be made. + if 'path' not in self: + res = GitWrapper.deploy(self) + event.log_info("%s" % res) + event.set_waiting(False) + event.set_success(True) + return + + # If the path does not exist, a warning will be raised and no pull or + # deploy will be made. + if not os.path.isdir(self['path']): + event.log_error("The repository '%s' does not exist locally. Make sure it was pulled properly without errors by reviewing the log." % self['path']) + event.set_waiting(False) + event.set_success(False) + return + + # If the path is not writable, a warning will be raised and no pull or + # deploy will be made. + if not os.access(self['path'], os.W_OK): + event.log_error("The path '%s' is not writable. Make sure that GAD has write access to that path." % self['path']) + event.set_waiting(False) + event.set_success(False) + return + + running_lock = Lock(os.path.join(self['path'], 'status_running')) + waiting_lock = Lock(os.path.join(self['path'], 'status_waiting')) + try: + + # Attempt to obtain the status_running lock + while not running_lock.obtain(): + + # If we're unable, try once to obtain the status_waiting lock + if not waiting_lock.has_lock() and not waiting_lock.obtain(): + event.log_error("Unable to obtain the status_running lock nor the status_waiting lock. Another process is already waiting, so we'll ignore the request.") + + # If we're unable to obtain the waiting lock, ignore the request + break + + # Keep on attempting to obtain the status_running lock until we succeed + time.sleep(5) + + n = 4 + res = None + while n > 0: + + # Attempt to pull up a maximum of 4 times + res = GitWrapper.pull(self) + + # Return code indicating success? + if res == 0: + break + + n -= 1 + + if 0 < n: + res = GitWrapper.deploy(self) + + #except Exception as e: + # logger.error('Error during \'pull\' or \'deploy\' operation on path: %s' % self['path']) + # logger.error(e) + # raise e + + finally: + + # Release the lock if it's ours + if running_lock.has_lock(): + running_lock.release() + + # Release the lock if it's ours + if waiting_lock.has_lock(): + waiting_lock.release() + + event.log_info("Deploy commands were executed") + event.set_waiting(False) + event.set_success(True) + diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/__init__.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/__init__.py new file mode 100644 index 0000000..f213339 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/__init__.py @@ -0,0 +1,53 @@ +from .bitbucket import BitBucketRequestParser +from .github import GitHubRequestParser +from .gitlab import GitLabRequestParser +from .gitlabci import GitLabCIRequestParser +from .generic import GenericRequestParser +from .coding import CodingRequestParser + + +def get_service_handler(request_headers, request_body, action): + """Parses the incoming request and attempts to determine whether + it originates from GitHub, GitLab or any other known service.""" + import json + + payload = json.loads(request_body) + + if not isinstance(payload, dict): + raise ValueError("Invalid JSON object") + + user_agent = 'user-agent' in request_headers and request_headers['user-agent'] + content_type = 'content-type' in request_headers and request_headers['content-type'] + + # Assume Coding if the X-Coding-Event HTTP header is set + if 'x-coding-event' in request_headers: + return CodingRequestParser + + # Assume GitLab if the X-Gitlab-Event HTTP header is set + elif 'x-gitlab-event' in request_headers: + + # Special Case for Gitlab CI + if content_type == "application/json" and "build_status" in payload: + return GitLabCIRequestParser + else: + return GitLabRequestParser + + # Assume GitHub if the X-GitHub-Event HTTP header is set + elif 'x-github-event' in request_headers: + + return GitHubRequestParser + + # Assume BitBucket if the User-Agent HTTP header is set to + # 'Bitbucket-Webhooks/2.0' (or something similar) + elif user_agent and user_agent.lower().find('bitbucket') != -1: + + return BitBucketRequestParser + + # This handles old GitLab requests and Gogs requests for example. + elif content_type == "application/json": + + action.log_info("Received event from unknown origin.") + return GenericRequestParser + + action.log_error("Unable to recognize request origin. Don't know how to handle the request.") + return \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/base.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/base.py new file mode 100644 index 0000000..f6cb9c9 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/base.py @@ -0,0 +1,29 @@ +class WebhookRequestParserBase(object): + """Abstract parent class for git service parsers. Contains helper + methods.""" + + def __init__(self, config): + self._config = config + + def get_matching_repo_configs(self, urls, action): + """Iterates over the various repo URLs provided as argument (git://, + ssh:// and https:// for the repo) and compare them to any repo URL + specified in the config""" + + configs = [] + for url in urls: + for repo_config in self._config['repositories']: + if repo_config in configs: + continue + if repo_config.get('match-url', repo_config.get('url')) == url: + configs.append(repo_config) + elif 'url_without_usernme' in repo_config and repo_config['url_without_usernme'] == url: + configs.append(repo_config) + + if len(configs) == 0: + action.log_warning('The URLs references in the webhook did not match any repository entry in the config. For this webhook to work, make sure you have at least one repository configured with one of the following URLs; %s' % ', '.join(urls)) + + return configs + + def validate_request(self, request_headers, request_body, repo_configs, action): + return True diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/bitbucket.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/bitbucket.py new file mode 100644 index 0000000..e5bd8b9 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/bitbucket.py @@ -0,0 +1,44 @@ +from .base import WebhookRequestParserBase + + +class BitBucketRequestParser(WebhookRequestParserBase): + + def get_matching_projects(self, request_headers, request_body, action): + import json + + data = json.loads(request_body) + + repo_urls = [] + + action.log_debug("Received event from BitBucket") + + if 'repository' not in data: + action.log_error("Unable to recognize data format") + return [] + + # One repository may posses multiple URLs for different protocols + for k in ['url', 'git_url', 'clone_url', 'ssh_url']: + if k in data['repository']: + repo_urls.append(data['repository'][k]) + + if 'full_name' in data['repository']: + repo_urls.append('git@bitbucket.org:%s.git' % data['repository']['full_name']) + + # Add a simplified version of the bitbucket HTTPS URL - without the username@bitbucket.com part. This is + # needed since the configured repositories might be configured using a different username. + repo_urls.append('https://bitbucket.org/%s.git' % (data['repository']['full_name'])) + + if 'fullName' in data['repository']: + # For Bitbucket Server add repository name (OWNER/REPO_NAME). + # Support "Post Webhooks for Bitbucket". + repo_urls.append(data['repository']['fullName']) + + if 'slug' in data['repository']: + # For Bitbucket Server add repository slug. + # Support "Post-Receive WebHooks" and "Post Webhooks for Bitbucket". + repo_urls.append(data['repository']['slug']) + + # Get a list of configured repositories that matches the incoming web hook reqeust + repo_configs = self.get_matching_repo_configs(repo_urls, action) + + return repo_configs diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/coding.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/coding.py new file mode 100644 index 0000000..588ea22 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/coding.py @@ -0,0 +1,40 @@ +from .base import WebhookRequestParserBase + + +class CodingRequestParser(WebhookRequestParserBase): + + def get_matching_projects(self, request_headers, request_body, action): + import json + + data = json.loads(request_body) + + repo_urls = [] + + coding_event = 'x-coding-event' in request_headers and request_headers['x-coding-event'] + + if 'repository' not in data: + action.log_error("Unable to recognize data format") + return [] + + # One repository may posses multiple URLs for different protocols + for k in ['web_url', 'https_url', 'ssh_url']: + if k in data['repository']: + repo_urls.append(data['repository'][k]) + + # Get a list of configured repositories that matches the incoming web hook reqeust + items = self.get_matching_repo_configs(repo_urls, action) + + repo_configs = [] + for repo_config in items: + # Validate secret token if present + if 'secret-token' in repo_config: + if 'token' not in data or not self.verify_token(repo_config['secret-token'], data['token']): + action.log_warning("Request token does not match the 'secret-token' configured for repository %s." % repo_config['url']) + continue + + repo_configs.append(repo_config) + + return repo_configs + + def verify_token(self, secret_token, request_token): + return secret_token == request_token diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/generic.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/generic.py new file mode 100644 index 0000000..f8e8f31 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/generic.py @@ -0,0 +1,28 @@ +from .base import WebhookRequestParserBase + + +class GenericRequestParser(WebhookRequestParserBase): + + def get_matching_projects(self, request_headers, request_body, action): + import json + + data = json.loads(request_body) + + repo_urls = [] + + action.log_info("Received event from unknown origin. Assume generic data format.") + + if 'repository' not in data: + action.log_error("Unable to recognize data format") + return [] + + # One repository may posses multiple URLs for different protocols + for k in ['url', 'git_http_url', 'git_ssh_url', 'http_url', 'ssh_url']: + if k in data['repository']: + repo_urls.append(data['repository'][k]) + + # Get a list of configured repositories that matches the incoming web hook reqeust + repo_configs = self.get_matching_repo_configs(repo_urls, action) + + return repo_configs + diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/github.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/github.py new file mode 100644 index 0000000..ef7eb6a --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/github.py @@ -0,0 +1,48 @@ +from .base import WebhookRequestParserBase + + +class GitHubRequestParser(WebhookRequestParserBase): + + def get_matching_projects(self, request_headers, request_body, action): + import json + + data = json.loads(request_body) + + repo_urls = [] + + github_event = 'x-github-event' in request_headers and request_headers['x-github-event'] + + action.log_info("Received '%s' event from GitHub" % github_event) + + if 'repository' not in data: + action.log_error("Unable to recognize data format") + return [] + + # One repository may posses multiple URLs for different protocols + for k in ['url', 'git_url', 'clone_url', 'ssh_url']: + if k in data['repository']: + repo_urls.append(data['repository'][k]) + + # Get a list of configured repositories that matches the incoming web hook reqeust + repo_configs = self.get_matching_repo_configs(repo_urls, action) + + return repo_configs + + def validate_request(self, request_headers, request_body, repo_configs, action): + + for repo_config in repo_configs: + + # Validate secret token if present + if 'secret-token' in repo_config and 'x-hub-signature' in request_headers: + if not self.verify_signature(repo_config['secret-token'], request_body, request_headers['x-hub-signature']): + action.log_info("Request signature does not match the 'secret-token' configured for repository %s." % repo_config['url']) + return False + + return True + + def verify_signature(self, token, body, signature): + import hashlib + import hmac + + result = "sha1=" + hmac.new(str(token), body, hashlib.sha1).hexdigest() + return result == signature diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/gitlab.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/gitlab.py new file mode 100644 index 0000000..c27e1d9 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/gitlab.py @@ -0,0 +1,42 @@ +from .base import WebhookRequestParserBase + + +class GitLabRequestParser(WebhookRequestParserBase): + + def get_matching_projects(self, request_headers, request_body, action): + import json + + data = json.loads(request_body) + + repo_urls = [] + + gitlab_event = 'x-gitlab-event' in request_headers and request_headers['x-gitlab-event'] + + action.log_info("Received '%s' event from GitLab" % gitlab_event) + + if 'repository' not in data: + action.log_error("Unable to recognize data format") + return [] + + # One repository may posses multiple URLs for different protocols + for k in ['url', 'git_http_url', 'git_ssh_url']: + if k in data['repository']: + repo_urls.append(data['repository'][k]) + + # Get a list of configured repositories that matches the incoming web hook reqeust + repo_configs = self.get_matching_repo_configs(repo_urls, action) + + return repo_configs + + def validate_request(self, request_headers, request_body, repo_configs, action): + + for repo_config in repo_configs: + + # Validate secret token if present + if 'secret-token' in repo_config and 'x-gitlab-token' in request_headers: + + if repo_config['secret-token'] != request_headers['x-gitlab-token']: + action.log_info("Request token does not match the 'secret-token' configured for repository %s." % repo_config['url']) + return False + + return True diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/parsers/gitlabci.py b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/gitlabci.py new file mode 100644 index 0000000..35d5ed4 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/parsers/gitlabci.py @@ -0,0 +1,31 @@ +from .base import WebhookRequestParserBase + + +class GitLabCIRequestParser(WebhookRequestParserBase): + + def get_matching_projects(self, request_headers, request_body, action): + import json + + data = json.loads(request_body) + + repo_urls = [] + + action.log_info('Received event from Gitlab CI') + + if 'repository' not in data: + action.log_error("Unable to recognize data format") + return [] + + # Only add repositories if the build is successful. Ignore it in other case. + if data['build_status'] == "success": + for k in ['url', 'git_http_url', 'git_ssh_url']: + for n in ['repository', 'project']: + if n in data and k in data[n]: + repo_urls.append(data[n][k]) + else: + action.log_warning("Gitlab CI build '%d' has status '%s'. Not pull will be done" % (data['build_id'], data['build_status'])) + + # Get a list of configured repositories that matches the incoming web hook reqeust + repo_configs = self.get_matching_repo_configs(repo_urls, action) + + return repo_configs diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/__init__.py b/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/__init__.py new file mode 100644 index 0000000..aad49c9 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/__init__.py @@ -0,0 +1,2 @@ +from .git import * +from .process import * \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/git.py b/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/git.py new file mode 100644 index 0000000..36f08ff --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/git.py @@ -0,0 +1,158 @@ +class GitWrapper(): + """Wraps the git client. Currently uses git through shell command + invocations.""" + + def __init__(self): + pass + + @staticmethod + def init(repo_config): + """Init remote url of the repo from the git server""" + import logging + from .process import ProcessWrapper + import os + import platform + + logger = logging.getLogger() + logger.info("Initializing repository %s" % repo_config['path']) + + commands = [] + + # On Windows, bash command needs to be run using bash.exe. This assumes bash.exe + # (typically installed under C:\Program Files\Git\bin) is in the system PATH. + if platform.system().lower() == "windows": + commands.append('bash -c "cd \\"' + repo_config['path'] + '\\" && unset GIT_DIR"') + else: + commands.append('unset GIT_DIR') + + commands.append('git remote set-url ' + repo_config['remote'] + " " + repo_config['url']) + commands.append('git fetch ' + repo_config['remote']) + commands.append('git checkout -f -B ' + repo_config['branch'] + ' -t ' + repo_config['remote'] + '/' + repo_config['branch']) + commands.append('git submodule update --init --recursive') + + # All commands need to success + for command in commands: + res = ProcessWrapper().call(command, cwd=repo_config['path'], shell=True, supressStderr=True) + + if res != 0: + logger.error("Command '%s' failed with exit code %s" % (command, res)) + break + + if res == 0 and os.path.isdir(repo_config['path']): + logger.info("Repository %s successfully initialized" % repo_config['path']) + else: + logger.error("Unable to init repository %s" % repo_config['path']) + + return int(res) + + @staticmethod + def pull(repo_config): + """Pulls the latest version of the repo from the git server""" + import logging + from .process import ProcessWrapper + import os + import platform + + logger = logging.getLogger() + logger.info("Updating repository %s" % repo_config['path']) + + # Only pull if there is actually a local copy of the repository + if 'path' not in repo_config: + logger.info('No local repository path configured, no pull will occure') + return 0 + + commands = [] + + # On Windows, bash command needs to be run using bash.exe. This assumes bash.exe + # (typically installed under C:\Program Files\Git\bin) is in the system PATH. + if platform.system().lower() == "windows": + commands.append('bash -c "cd \\"' + repo_config['path'] + '\\" && unset GIT_DIR"') + else: + commands.append('unset GIT_DIR') + + if "prepull" in repo_config: + commands.append(repo_config['prepull']) + + commands.append('git fetch ' + repo_config['remote']) + commands.append('git reset --hard ' + repo_config['remote'] + "/" + repo_config['branch']) + commands.append('git submodule update --init --recursive') + + if "postpull" in repo_config: + commands.append(repo_config['postpull']) + + # All commands need to success + for command in commands: + res = ProcessWrapper().call(command, cwd=repo_config['path'], shell=True, supressStderr=True) + + if res != 0: + logger.error("Command '%s' failed with exit code %s" % (command, res)) + break + + if res == 0 and os.path.isdir(repo_config['path']): + logger.info("Repository %s successfully updated" % repo_config['path']) + else: + logger.error("Unable to update repository %s" % repo_config['path']) + + return int(res) + + @staticmethod + def clone(repo_config): + """Clones the latest version of the repo from the git server""" + import logging + from .process import ProcessWrapper + import os + import platform + + logger = logging.getLogger() + logger.info("Cloning repository %s" % repo_config['path']) + + # Only pull if there is actually a local copy of the repository + if 'path' not in repo_config: + logger.info('No local repository path configured, no clone will occure') + return 0 + + commands = [] + commands.append('unset GIT_DIR') + commands.append('git clone --recursive ' + repo_config['url'] + ' -b ' + repo_config['branch'] + ' ' + repo_config['path']) + + # All commands need to success + for command in commands: + res = ProcessWrapper().call(command, shell=True) + + if res != 0: + logger.error("Command '%s' failed with exit code %s" % (command, res)) + break + + if res == 0 and os.path.isdir(repo_config['path']): + logger.info("Repository %s successfully cloned" % repo_config['url']) + else: + logger.error("Unable to clone repository %s" % repo_config['url']) + + return int(res) + + @staticmethod + def deploy(repo_config): + """Executes any supplied post-pull deploy command""" + from .process import ProcessWrapper + import logging + logger = logging.getLogger() + + if 'path' in repo_config: + path = repo_config['path'] + + if not 'deploy_commands' in repo_config or len(repo_config['deploy_commands']) == 0: + logger.info('No deploy commands configured') + return [] + + logger.info('Executing %s deploy commands' % str(len(repo_config['deploy_commands']))) + + # Use repository path as default cwd when executing deploy commands + cwd = (repo_config['path'] if 'path' in repo_config else None) + + res = [] + for cmd in repo_config['deploy_commands']: + res.append(ProcessWrapper().call([cmd], cwd=cwd, shell=True)) + + logger.info('%s commands executed with status; %s' % (str(len(res)), str(res))) + + return res diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/process.py b/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/process.py new file mode 100644 index 0000000..b33f580 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wrappers/process.py @@ -0,0 +1,43 @@ +class ProcessWrapper(): + """Wraps the subprocess popen method and provides logging.""" + + def __init__(self): + pass + + @staticmethod + def call(*popenargs, **kwargs): + """Run command with arguments. Wait for command to complete. Sends + output to logging module. The arguments are the same as for the Popen + constructor.""" + + from subprocess import Popen, PIPE + import logging + logger = logging.getLogger() + + kwargs['stdout'] = PIPE + kwargs['stderr'] = PIPE + + supressStderr = None + if 'supressStderr' in kwargs: + supressStderr = kwargs['supressStderr'] + del kwargs['supressStderr'] + + p = Popen(*popenargs, **kwargs) + stdout, stderr = p.communicate() + + # Decode bytes to string (assume utf-8 encoding) + stdout = stdout.decode("utf-8") + stderr = stderr.decode("utf-8") + + if stdout: + for line in stdout.strip().split("\n"): + logger.info(line) + + if stderr: + for line in stderr.strip().split("\n"): + if supressStderr: + logger.info(line) + else: + logger.error(line) + + return p.returncode \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wsserver.py b/deploy/Git-Auto-Deploy/gitautodeploy/wsserver.py new file mode 100644 index 0000000..1ce2e59 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wsserver.py @@ -0,0 +1,117 @@ +from .events import SystemEvent + +try: + from autobahn.websocket import WebSocketServerProtocol +except ImportError: + WebSocketServerProtocol = object + +def WebSocketClientHandlerFactory(config, clients, event_store, server_status): + """Factory method for webhook request handler class""" + + class WebSocketClientHandler(WebSocketServerProtocol, object): + + def __init__(self, *args, **kwargs): + self._config = config + self.clients = clients + self._event_store = event_store + self._server_status = server_status + import logging + self.logger = logging.getLogger() + super(WebSocketClientHandler, self).__init__(*args, **kwargs) + + def onConnect(self, request): + self.logger.info("Client connecting: {0}".format(request.peer)) + + # Web UI needs to be enabled + if not self.validate_web_ui_enabled(): + return + + # Client needs to be whitelisted + if not self.validate_web_ui_whitelist(): + return + + def onOpen(self): + self.logger.info("WebSocket connection open.") + + def onMessage(self, payload, isBinary): + import json + + if isBinary: + return + + try: + data = json.loads(payload) + + # Handle authentication requests + if 'type' in data and data['type'] == 'authenticate': + + # Verify auth key + if 'auth-key' in data and data['auth-key'] == self._server_status['auth-key']: + self.clients.append(self) + + # Let the client know that they are authenticated + self.sendMessage(json.dumps({ + "type": "authenticated" + })) + return + + else: + self.logger.error("Recieved bad auth key.") + + self.sendMessage(json.dumps({ + "type": "bad-auth-key" + })) + return + + except Exception as e: + + self.logger.error("Unable to interpret incoming message: %s" % e) + + if self not in self.clients: + self.logger.error("Recieved message form unauthenticated client, closing connection.") + self.sendClose() + return + + #self.logger.info("WebSocket connection open.") + #if isBinary: + # self.logger.info("Binary message received: {0} bytes".format(len(payload))) + #else: + # self.logger.info("Text message received: {0}".format(payload.decode('utf8'))) + + #for client in self.clients: + # client.sendMessage(payload, isBinary) + + # echo back message verbatim + #self.sendMessage(payload, isBinary) + + def onClose(self, wasClean, code, reason): + self.logger.info("WebSocket connection closed: {0}".format(reason)) + + if self in self.clients: + self.clients.remove(self) + + def validate_web_ui_enabled(self): + """Verify that the Web UI is enabled""" + + if self._config['web-ui-enabled']: + return True + + self.sendClose() + return False + + def validate_web_ui_whitelist(self): + """Verify that the client address is whitelisted""" + + # Allow all if whitelist is empty + if len(self._config['web-ui-whitelist']) == 0: + return True + + # Verify that client IP is whitelisted + if self.peer.host in self._config['web-ui-whitelist']: + return True + + self.sendClose() + logger.info("Unautorized connection attempt from %s" % self.peer.host) + return False + + return WebSocketClientHandler diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/asset-manifest.json b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/asset-manifest.json new file mode 100644 index 0000000..7ad27c8 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/asset-manifest.json @@ -0,0 +1,6 @@ +{ + "main.css": "static/css/main.e20565bf.css", + "main.css.map": "static/css/main.e20565bf.css.map", + "main.js": "static/js/main.58631280.js", + "main.js.map": "static/js/main.58631280.js.map" +} \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/index.html b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/index.html new file mode 100644 index 0000000..5e8ae99 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/index.html @@ -0,0 +1 @@ +Git-Auto-Deploy Web UI
\ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/css/main.e20565bf.css b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/css/main.e20565bf.css new file mode 100644 index 0000000..a8c8cfd --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/css/main.e20565bf.css @@ -0,0 +1,2 @@ +body,html{height:100%;margin:0;padding:0}body{background:#f2f2f2} +/*# sourceMappingURL=main.e20565bf.css.map*/ \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/css/main.e20565bf.css.map b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/css/main.e20565bf.css.map new file mode 100644 index 0000000..140286c --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/css/main.e20565bf.css.map @@ -0,0 +1 @@ +{"version":3,"sources":[],"names":[],"mappings":"","file":"static/css/main.e20565bf.css","sourceRoot":""} \ No newline at end of file diff --git a/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/js/main.58631280.js b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/js/main.58631280.js new file mode 100644 index 0000000..7c69691 --- /dev/null +++ b/deploy/Git-Auto-Deploy/gitautodeploy/wwwroot/static/js/main.58631280.js @@ -0,0 +1,14 @@ +!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="/",t(0)}(function(e){for(var t in e)if(Object.prototype.hasOwnProperty.call(e,t))switch(typeof e[t]){case"function":break;case"object":e[t]=function(t){var n=t.slice(1),r=e[t[0]];return function(e,t,a){r.apply(this,[e,t,a].concat(n))}}(e[t]);break;default:e[t]=e[e[t]]}return e}([function(e,t,n){n(197),e.exports=n(226)},function(e,t,n){(function(e){!function(t,n){e.exports=n()}(this,function(){"use strict";function t(){return yr.apply(null,arguments)}function r(e){yr=e}function a(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function i(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function o(e){var t;for(t in e)return!1;return!0}function s(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function u(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function d(e,t){var n,r=[];for(n=0;n0)for(n in gr)r=gr[n],a=t[r],y(a)||(e[r]=a);return e}function v(e){M(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),Lr===!1&&(Lr=!0,t.updateOffset(this),Lr=!1)}function g(e){return e instanceof v||null!=e&&null!=e._isAMomentObject}function L(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function Y(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=L(t)),n}function k(e,t,n){var r,a=Math.min(e.length,t.length),i=Math.abs(e.length-t.length),o=0;for(r=0;r0?"future":"past"];return T(n)?n(t):n.replace(/%s/i,t)}function N(e,t){var n=e.toLowerCase();Cr[n]=Cr[n+"s"]=Cr[t]=e}function R(e){return"string"==typeof e?Cr[e]||Cr[e.toLowerCase()]:void 0}function I(e){var t,n,r={};for(n in e)l(e,n)&&(t=R(n),t&&(r[t]=e[n]));return r}function W(e,t){Pr[e]=t}function F(e){var t=[];for(var n in e)t.push({unit:n,priority:Pr[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}function U(e,n){return function(r){return null!=r?(B(this,e,r),t.updateOffset(this,n),this):z(this,e)}}function z(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function B(e,t,n){e.isValid()&&e._d["set"+(e._isUTC?"UTC":"")+t](n)}function V(e){return e=R(e),T(this[e])?this[e]():this}function J(e,t){if("object"==typeof e){e=I(e);for(var n=F(e),r=0;r=0;return(i?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+r}function G(e,t,n,r){var a=r;"string"==typeof r&&(a=function(){return this[r]()}),e&&(Nr[e]=a),t&&(Nr[t[0]]=function(){return q(a.apply(this,arguments),t[1],t[2])}),n&&(Nr[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),e)})}function K(e){return e.match(/\[[\s\S]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"")}function $(e){var t,n,r=e.match(Hr);for(t=0,n=r.length;t=0&&Ar.test(e);)e=e.replace(Ar,n),Ar.lastIndex=0,r-=1;return e}function Z(e,t,n){ta[e]=T(t)?t:function(e,r){return e&&n?n:t}}function ee(e,t){return l(ta,e)?ta[e](t._strict,t._locale):new RegExp(te(e))}function te(e){return ne(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,r,a){return t||n||r||a}))}function ne(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function re(e,t){var n,r=t;for("string"==typeof e&&(e=[e]),s(t)&&(r=function(e,n){n[t]=Y(e)}),n=0;n=0&&isFinite(s.getFullYear())&&s.setFullYear(e),s}function Le(e){var t=new Date(Date.UTC.apply(null,arguments));return e<100&&e>=0&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e),t}function Ye(e,t,n){var r=7+t-n,a=(7+Le(e,0,r).getUTCDay()-t)%7;return-a+r-1}function ke(e,t,n,r,a){var i,o,s=(7+n-r)%7,u=Ye(e,r,a),d=1+7*(t-1)+s+u;return d<=0?(i=e-1,o=ye(i)+d):d>ye(e)?(i=e+1,o=d-ye(e)):(i=e,o=d),{year:i,dayOfYear:o}}function we(e,t,n){var r,a,i=Ye(e.year(),t,n),o=Math.floor((e.dayOfYear()-i-1)/7)+1;return o<1?(a=e.year()-1,r=o+be(a,t,n)):o>be(e.year(),t,n)?(r=o-be(e.year(),t,n),a=e.year()+1):(a=e.year(),r=o),{week:r,year:a}}function be(e,t,n){var r=Ye(e,t,n),a=Ye(e+1,t,n);return(ye(e)-r+a)/7}function De(e){return we(e,this._week.dow,this._week.doy).week}function Te(){return this._week.dow}function Se(){return this._week.doy}function xe(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")}function Ee(e){var t=we(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")}function je(e,t){return"string"!=typeof e?e:isNaN(e)?(e=t.weekdaysParse(e),"number"==typeof e?e:null):parseInt(e,10)}function Ce(e,t){return"string"==typeof e?t.weekdaysParse(e)%7||7:isNaN(e)?null:e}function Pe(e,t){return e?a(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(t)?"format":"standalone"][e.day()]:this._weekdays}function He(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort}function Ae(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin}function Oe(e,t,n){var r,a,i,o=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],r=0;r<7;++r)i=_([2e3,1]).day(r),this._minWeekdaysParse[r]=this.weekdaysMin(i,"").toLocaleLowerCase(),this._shortWeekdaysParse[r]=this.weekdaysShort(i,"").toLocaleLowerCase(),this._weekdaysParse[r]=this.weekdays(i,"").toLocaleLowerCase();return n?"dddd"===t?(a=_a.call(this._weekdaysParse,o),a!==-1?a:null):"ddd"===t?(a=_a.call(this._shortWeekdaysParse,o),a!==-1?a:null):(a=_a.call(this._minWeekdaysParse,o),a!==-1?a:null):"dddd"===t?(a=_a.call(this._weekdaysParse,o),a!==-1?a:(a=_a.call(this._shortWeekdaysParse,o),a!==-1?a:(a=_a.call(this._minWeekdaysParse,o),a!==-1?a:null))):"ddd"===t?(a=_a.call(this._shortWeekdaysParse,o),a!==-1?a:(a=_a.call(this._weekdaysParse,o),a!==-1?a:(a=_a.call(this._minWeekdaysParse,o),a!==-1?a:null))):(a=_a.call(this._minWeekdaysParse,o),a!==-1?a:(a=_a.call(this._weekdaysParse,o),a!==-1?a:(a=_a.call(this._shortWeekdaysParse,o),a!==-1?a:null)))}function Ne(e,t,n){var r,a,i;if(this._weekdaysParseExact)return Oe.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),r=0;r<7;r++){if(a=_([2e3,1]).day(r),n&&!this._fullWeekdaysParse[r]&&(this._fullWeekdaysParse[r]=new RegExp("^"+this.weekdays(a,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[r]=new RegExp("^"+this.weekdaysShort(a,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[r]=new RegExp("^"+this.weekdaysMin(a,"").replace(".",".?")+"$","i")),this._weekdaysParse[r]||(i="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[r]=new RegExp(i.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[r].test(e))return r;if(n&&"ddd"===t&&this._shortWeekdaysParse[r].test(e))return r;if(n&&"dd"===t&&this._minWeekdaysParse[r].test(e))return r;if(!n&&this._weekdaysParse[r].test(e))return r}}function Re(e){if(!this.isValid())return null!=e?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=je(e,this.localeData()),this.add(e-t,"d")):t}function Ie(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")}function We(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=Ce(e,this.localeData());return this.day(this.day()%7?t:t-7)}return this.day()||7}function Fe(e){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(l(this,"_weekdaysRegex")||(this._weekdaysRegex=ka),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)}function Ue(e){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(l(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=wa),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function ze(e){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(l(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ba),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Be(){function e(e,t){return t.length-e.length}var t,n,r,a,i,o=[],s=[],u=[],d=[];for(t=0;t<7;t++)n=_([2e3,1]).day(t),r=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),i=this.weekdays(n,""),o.push(r),s.push(a),u.push(i),d.push(r),d.push(a),d.push(i);for(o.sort(e),s.sort(e),u.sort(e),d.sort(e),t=0;t<7;t++)s[t]=ne(s[t]),u[t]=ne(u[t]),d[t]=ne(d[t]);this._weekdaysRegex=new RegExp("^("+d.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Ve(){return this.hours()%12||12}function Je(){return this.hours()||24}function qe(e,t){G(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Ge(e,t){return t._meridiemParse}function Ke(e){return"p"===(e+"").toLowerCase().charAt(0)}function $e(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"}function Xe(e){return e?e.toLowerCase().replace("_","-"):e}function Qe(e){for(var t,n,r,a,i=0;i0;){if(r=Ze(a.slice(0,t).join("-")))return r;if(n&&n.length>=t&&k(a,n,!0)>=t-1)break;t--}i++}return null}function Ze(t){var r=null;if(!Ea[t]&&"undefined"!=typeof e&&e&&e.exports)try{r=Da._abbr,n(248)("./"+t),et(r)}catch(e){}return Ea[t]}function et(e,t){var n;return e&&(n=y(t)?rt(e):tt(e,t),n&&(Da=n)),Da._abbr}function tt(e,t){if(null!==t){var n=xa;if(t.abbr=e,null!=Ea[e])D("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."),n=Ea[e]._config;else if(null!=t.parentLocale){if(null==Ea[t.parentLocale])return ja[t.parentLocale]||(ja[t.parentLocale]=[]),ja[t.parentLocale].push({name:e,config:t}),null;n=Ea[t.parentLocale]._config}return Ea[e]=new E(x(n,t)),ja[e]&&ja[e].forEach(function(e){tt(e.name,e.config)}),et(e),Ea[e]}return delete Ea[e],null}function nt(e,t){if(null!=t){var n,r=xa;null!=Ea[e]&&(r=Ea[e]._config),t=x(r,t),n=new E(t),n.parentLocale=Ea[e],Ea[e]=n,et(e)}else null!=Ea[e]&&(null!=Ea[e].parentLocale?Ea[e]=Ea[e].parentLocale:null!=Ea[e]&&delete Ea[e]);return Ea[e]}function rt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return Da;if(!a(e)){if(t=Ze(e))return t;e=[e]}return Qe(e)}function at(){return br(Ea)}function it(e){var t,n=e._a;return n&&h(e).overflow===-2&&(t=n[aa]<0||n[aa]>11?aa:n[ia]<1||n[ia]>oe(n[ra],n[aa])?ia:n[oa]<0||n[oa]>24||24===n[oa]&&(0!==n[sa]||0!==n[ua]||0!==n[da])?oa:n[sa]<0||n[sa]>59?sa:n[ua]<0||n[ua]>59?ua:n[da]<0||n[da]>999?da:-1,h(e)._overflowDayOfYear&&(tia)&&(t=ia),h(e)._overflowWeeks&&t===-1&&(t=la),h(e)._overflowWeekday&&t===-1&&(t=ca),h(e).overflow=t),e}function ot(e){var t,n,r,a,i,o,s=e._i,u=Ca.exec(s)||Pa.exec(s);if(u){for(h(e).iso=!0,t=0,n=Aa.length;tye(a)&&(h(e)._overflowDayOfYear=!0),n=Le(a,0,e._dayOfYear),e._a[aa]=n.getUTCMonth(),e._a[ia]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=i[t]=r[t];for(;t<7;t++)e._a[t]=i[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[oa]&&0===e._a[sa]&&0===e._a[ua]&&0===e._a[da]&&(e._nextDay=!0,e._a[oa]=0),e._d=(e._useUTC?Le:ge).apply(null,i),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[oa]=24)}}function ct(e){var t,n,r,a,i,o,s,u;if(t=e._w,null!=t.GG||null!=t.W||null!=t.E)i=1,o=4,n=ut(t.GG,e._a[ra],we(gt(),1,4).year),r=ut(t.W,1),a=ut(t.E,1),(a<1||a>7)&&(u=!0);else{i=e._locale._week.dow,o=e._locale._week.doy;var d=we(gt(),i,o);n=ut(t.gg,e._a[ra],d.year),r=ut(t.w,d.week),null!=t.d?(a=t.d,(a<0||a>6)&&(u=!0)):null!=t.e?(a=t.e+i,(t.e<0||t.e>6)&&(u=!0)):a=i}r<1||r>be(n,i,o)?h(e)._overflowWeeks=!0:null!=u?h(e)._overflowWeekday=!0:(s=ke(n,r,a,i,o),e._a[ra]=s.year,e._dayOfYear=s.dayOfYear)}function _t(e){if(e._f===t.ISO_8601)return void ot(e);e._a=[],h(e).empty=!0;var n,r,a,i,o,s=""+e._i,u=s.length,d=0;for(a=Q(e._f,e._locale).match(Hr)||[],n=0;n0&&h(e).unusedInput.push(o),s=s.slice(s.indexOf(r)+r.length),d+=r.length),Nr[i]?(r?h(e).empty=!1:h(e).unusedTokens.push(i),ie(i,r,e)):e._strict&&!r&&h(e).unusedTokens.push(i);h(e).charsLeftOver=u-d,s.length>0&&h(e).unusedInput.push(s),e._a[oa]<=12&&h(e).bigHour===!0&&e._a[oa]>0&&(h(e).bigHour=void 0),h(e).parsedDateParts=e._a.slice(0),h(e).meridiem=e._meridiem,e._a[oa]=mt(e._locale,e._a[oa],e._meridiem),lt(e),it(e)}function mt(e,t,n){var r;return null==n?t:null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?(r=e.isPM(n),r&&t<12&&(t+=12),r||12!==t||(t=0),t):t}function ht(e){var t,n,r,a,i;if(0===e._f.length)return h(e).invalidFormat=!0,void(e._d=new Date(NaN));for(a=0;athis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Rt(){if(!y(this._isDSTShifted))return this._isDSTShifted;var e={};if(M(e,this),e=yt(e),e._a){var t=e._isUTC?_(e._a):gt(e._a);this._isDSTShifted=this.isValid()&&k(e._a,t.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function It(){return!!this.isValid()&&!this._isUTC}function Wt(){return!!this.isValid()&&this._isUTC}function Ft(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Ut(e,t){var n,r,a,i=e,o=null;return bt(e)?i={ms:e._milliseconds,d:e._days,M:e._months}:s(e)?(i={},t?i[t]=e:i.milliseconds=e):(o=Ua.exec(e))?(n="-"===o[1]?-1:1,i={y:0,d:Y(o[ia])*n,h:Y(o[oa])*n,m:Y(o[sa])*n,s:Y(o[ua])*n,ms:Y(Dt(1e3*o[da]))*n}):(o=za.exec(e))?(n="-"===o[1]?-1:1,i={y:zt(o[2],n),M:zt(o[3],n),w:zt(o[4],n),d:zt(o[5],n),h:zt(o[6],n),m:zt(o[7],n),s:zt(o[8],n)}):null==i?i={}:"object"==typeof i&&("from"in i||"to"in i)&&(a=Vt(gt(i.from),gt(i.to)),i={},i.ms=a.milliseconds,i.M=a.months),r=new wt(i),bt(e)&&l(e,"_locale")&&(r._locale=e._locale),r}function zt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function Bt(e,t){var n={milliseconds:0,months:0};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function Vt(e,t){var n;return e.isValid()&&t.isValid()?(t=xt(t,e),e.isBefore(t)?n=Bt(e,t):(n=Bt(t,e),n.milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function Jt(e,t){return function(n,r){var a,i;return null===r||isNaN(+r)||(D(t,"moment()."+t+"(period, number) is deprecated. Please use moment()."+t+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),i=n,n=r,r=i),n="string"==typeof n?+n:n,a=Ut(n,r),qt(this,a,e),this}}function qt(e,n,r,a){var i=n._milliseconds,o=Dt(n._days),s=Dt(n._months);e.isValid()&&(a=null==a||a,i&&e._d.setTime(e._d.valueOf()+i*r),o&&B(e,"Date",z(e,"Date")+o*r),s&&ce(e,z(e,"Month")+s*r),a&&t.updateOffset(e,o||s))}function Gt(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"}function Kt(e,n){var r=e||gt(),a=xt(r,this).startOf("day"),i=t.calendarFormat(this,a)||"sameElse",o=n&&(T(n[i])?n[i].call(this,r):n[i]);return this.format(o||this.localeData().calendar(i,this,gt(r)))}function $t(){return new v(this)}function Xt(e,t){var n=g(e)?e:gt(e);return!(!this.isValid()||!n.isValid())&&(t=R(y(t)?"millisecond":t),"millisecond"===t?this.valueOf()>n.valueOf():n.valueOf()i&&(t=i),Hn.call(this,e,t,n,r,a))}function Hn(e,t,n,r,a){var i=ke(e,t,n,r,a),o=Le(i.year,0,i.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function An(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)}function On(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")}function Nn(e,t){t[da]=Y(1e3*("0."+e))}function Rn(){return this._isUTC?"UTC":""; +}function In(){return this._isUTC?"Coordinated Universal Time":""}function Wn(e){return gt(1e3*e)}function Fn(){return gt.apply(null,arguments).parseZone()}function Un(e){return e}function zn(e,t,n,r){var a=rt(),i=_().set(r,t);return a[n](i,e)}function Bn(e,t,n){if(s(e)&&(t=e,e=void 0),e=e||"",null!=t)return zn(e,t,n,"month");var r,a=[];for(r=0;r<12;r++)a[r]=zn(e,r,n,"month");return a}function Vn(e,t,n,r){"boolean"==typeof e?(s(t)&&(n=t,t=void 0),t=t||""):(t=e,n=t,e=!1,s(t)&&(n=t,t=void 0),t=t||"");var a=rt(),i=e?a._week.dow:0;if(null!=n)return zn(t,(n+i)%7,r,"day");var o,u=[];for(o=0;o<7;o++)u[o]=zn(t,(o+i)%7,r,"day");return u}function Jn(e,t){return Bn(e,t,"months")}function qn(e,t){return Bn(e,t,"monthsShort")}function Gn(e,t,n){return Vn(e,t,n,"weekdays")}function Kn(e,t,n){return Vn(e,t,n,"weekdaysShort")}function $n(e,t,n){return Vn(e,t,n,"weekdaysMin")}function Xn(){var e=this._data;return this._milliseconds=ei(this._milliseconds),this._days=ei(this._days),this._months=ei(this._months),e.milliseconds=ei(e.milliseconds),e.seconds=ei(e.seconds),e.minutes=ei(e.minutes),e.hours=ei(e.hours),e.months=ei(e.months),e.years=ei(e.years),this}function Qn(e,t,n,r){var a=Ut(t,n);return e._milliseconds+=r*a._milliseconds,e._days+=r*a._days,e._months+=r*a._months,e._bubble()}function Zn(e,t){return Qn(this,e,t,1)}function er(e,t){return Qn(this,e,t,-1)}function tr(e){return e<0?Math.floor(e):Math.ceil(e)}function nr(){var e,t,n,r,a,i=this._milliseconds,o=this._days,s=this._months,u=this._data;return i>=0&&o>=0&&s>=0||i<=0&&o<=0&&s<=0||(i+=864e5*tr(ar(s)+o),o=0,s=0),u.milliseconds=i%1e3,e=L(i/1e3),u.seconds=e%60,t=L(e/60),u.minutes=t%60,n=L(t/60),u.hours=n%24,o+=L(n/24),a=L(rr(o)),s+=a,o-=tr(ar(a)),r=L(s/12),s%=12,u.days=o,u.months=s,u.years=r,this}function rr(e){return 4800*e/146097}function ar(e){return 146097*e/4800}function ir(e){var t,n,r=this._milliseconds;if(e=R(e),"month"===e||"year"===e)return t=this._days+r/864e5,n=this._months+rr(t),"month"===e?n:n/12;switch(t=this._days+Math.round(ar(this._months)),e){case"week":return t/7+r/6048e5;case"day":return t+r/864e5;case"hour":return 24*t+r/36e5;case"minute":return 1440*t+r/6e4;case"second":return 86400*t+r/1e3;case"millisecond":return Math.floor(864e5*t)+r;default:throw new Error("Unknown unit "+e)}}function or(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*Y(this._months/12)}function sr(e){return function(){return this.as(e)}}function ur(e){return e=R(e),this[e+"s"]()}function dr(e){return function(){return this._data[e]}}function lr(){return L(this.days()/7)}function cr(e,t,n,r,a){return a.relativeTime(t||1,!!n,e,r)}function _r(e,t,n){var r=Ut(e).abs(),a=fi(r.as("s")),i=fi(r.as("m")),o=fi(r.as("h")),s=fi(r.as("d")),u=fi(r.as("M")),d=fi(r.as("y")),l=a0,l[4]=n,cr.apply(null,l)}function mr(e){return void 0===e?fi:"function"==typeof e&&(fi=e,!0)}function hr(e,t){return void 0!==yi[e]&&(void 0===t?yi[e]:(yi[e]=t,!0))}function pr(e){var t=this.localeData(),n=_r(this,!e,t);return e&&(n=t.pastFuture(+this,n)),t.postformat(n)}function fr(){var e,t,n,r=Mi(this._milliseconds)/1e3,a=Mi(this._days),i=Mi(this._months);e=L(r/60),t=L(e/60),r%=60,e%=60,n=L(i/12),i%=12;var o=n,s=i,u=a,d=t,l=e,c=r,_=this.asSeconds();return _?(_<0?"-":"")+"P"+(o?o+"Y":"")+(s?s+"M":"")+(u?u+"D":"")+(d||l||c?"T":"")+(d?d+"H":"")+(l?l+"M":"")+(c?c+"S":""):"P0D"}var yr,Mr;Mr=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,r=0;r68?1900:2e3)};var Ma=U("FullYear",!0);G("w",["ww",2],"wo","week"),G("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),W("week",5),W("isoWeek",5),Z("w",zr),Z("ww",zr,Ir),Z("W",zr),Z("WW",zr,Ir),ae(["w","ww","W","WW"],function(e,t,n,r){t[r.substr(0,1)]=Y(e)});var va={dow:0,doy:6};G("d",0,"do","day"),G("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),G("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),G("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),G("e",0,0,"weekday"),G("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),W("day",11),W("weekday",11),W("isoWeekday",11),Z("d",zr),Z("e",zr),Z("E",zr),Z("dd",function(e,t){return t.weekdaysMinRegex(e)}),Z("ddd",function(e,t){return t.weekdaysShortRegex(e)}),Z("dddd",function(e,t){return t.weekdaysRegex(e)}),ae(["dd","ddd","dddd"],function(e,t,n,r){var a=n._locale.weekdaysParse(e,r,n._strict);null!=a?t.d=a:h(n).invalidWeekday=e}),ae(["d","e","E"],function(e,t,n,r){t[r]=Y(e)});var ga="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),La="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ya="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ka=ea,wa=ea,ba=ea;G("H",["HH",2],0,"hour"),G("h",["hh",2],0,Ve),G("k",["kk",2],0,Je),G("hmm",0,0,function(){return""+Ve.apply(this)+q(this.minutes(),2)}),G("hmmss",0,0,function(){return""+Ve.apply(this)+q(this.minutes(),2)+q(this.seconds(),2)}),G("Hmm",0,0,function(){return""+this.hours()+q(this.minutes(),2)}),G("Hmmss",0,0,function(){return""+this.hours()+q(this.minutes(),2)+q(this.seconds(),2)}),qe("a",!0),qe("A",!1),N("hour","h"),W("hour",13),Z("a",Ge),Z("A",Ge),Z("H",zr),Z("h",zr),Z("HH",zr,Ir),Z("hh",zr,Ir),Z("hmm",Br),Z("hmmss",Vr),Z("Hmm",Br),Z("Hmmss",Vr),re(["H","HH"],oa),re(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),re(["h","hh"],function(e,t,n){t[oa]=Y(e),h(n).bigHour=!0}),re("hmm",function(e,t,n){var r=e.length-2;t[oa]=Y(e.substr(0,r)),t[sa]=Y(e.substr(r)),h(n).bigHour=!0}),re("hmmss",function(e,t,n){var r=e.length-4,a=e.length-2;t[oa]=Y(e.substr(0,r)),t[sa]=Y(e.substr(r,2)),t[ua]=Y(e.substr(a)),h(n).bigHour=!0}),re("Hmm",function(e,t,n){var r=e.length-2;t[oa]=Y(e.substr(0,r)),t[sa]=Y(e.substr(r))}),re("Hmmss",function(e,t,n){var r=e.length-4,a=e.length-2;t[oa]=Y(e.substr(0,r)),t[sa]=Y(e.substr(r,2)),t[ua]=Y(e.substr(a))});var Da,Ta=/[ap]\.?m?\.?/i,Sa=U("Hours",!0),xa={calendar:Dr,longDateFormat:Tr,invalidDate:Sr,ordinal:xr,ordinalParse:Er,relativeTime:jr,months:ha,monthsShort:pa,week:va,weekdays:ga,weekdaysMin:Ya,weekdaysShort:La,meridiemParse:Ta},Ea={},ja={},Ca=/^\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)?)?$/,Pa=/^\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)?)?$/,Ha=/Z|[+-]\d\d(?::?\d\d)?/,Aa=[["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/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Oa=[["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/]],Na=/^\/?Date\((\-?\d+)/i;t.createFromInputFallback=b("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),t.ISO_8601=function(){};var Ra=b("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=gt.apply(null,arguments);return this.isValid()&&e.isValid()?ethis?this:e:f()}),Wa=function(){return Date.now?Date.now():+new Date};Tt("Z",":"),Tt("ZZ",""),Z("Z",Qr),Z("ZZ",Qr),re(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=St(Qr,e)});var Fa=/([\+\-]|\d\d)/gi;t.updateOffset=function(){};var Ua=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,za=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Ut.fn=wt.prototype;var Ba=Jt(1,"add"),Va=Jt(-1,"subtract");t.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",t.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Ja=b("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});G(0,["gg",2],0,function(){return this.weekYear()%100}),G(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Sn("gggg","weekYear"),Sn("ggggg","weekYear"),Sn("GGGG","isoWeekYear"),Sn("GGGGG","isoWeekYear"),N("weekYear","gg"),N("isoWeekYear","GG"),W("weekYear",1),W("isoWeekYear",1),Z("G",$r),Z("g",$r),Z("GG",zr,Ir),Z("gg",zr,Ir),Z("GGGG",qr,Fr),Z("gggg",qr,Fr),Z("GGGGG",Gr,Ur),Z("ggggg",Gr,Ur),ae(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,r){t[r.substr(0,2)]=Y(e)}),ae(["gg","GG"],function(e,n,r,a){n[a]=t.parseTwoDigitYear(e)}),G("Q",0,"Qo","quarter"),N("quarter","Q"),W("quarter",7),Z("Q",Rr),re("Q",function(e,t){t[aa]=3*(Y(e)-1)}),G("D",["DD",2],"Do","date"),N("date","D"),W("date",9),Z("D",zr),Z("DD",zr,Ir),Z("Do",function(e,t){return e?t._ordinalParse:t._ordinalParseLenient}),re(["D","DD"],ia),re("Do",function(e,t){t[ia]=Y(e.match(zr)[0],10)});var qa=U("Date",!0);G("DDD",["DDDD",3],"DDDo","dayOfYear"),N("dayOfYear","DDD"),W("dayOfYear",4),Z("DDD",Jr),Z("DDDD",Wr),re(["DDD","DDDD"],function(e,t,n){n._dayOfYear=Y(e)}),G("m",["mm",2],0,"minute"),N("minute","m"),W("minute",14),Z("m",zr),Z("mm",zr,Ir),re(["m","mm"],sa);var Ga=U("Minutes",!1);G("s",["ss",2],0,"second"),N("second","s"),W("second",15),Z("s",zr),Z("ss",zr,Ir),re(["s","ss"],ua);var Ka=U("Seconds",!1);G("S",0,0,function(){return~~(this.millisecond()/100)}),G(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),G(0,["SSS",3],0,"millisecond"),G(0,["SSSS",4],0,function(){return 10*this.millisecond()}),G(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),G(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),G(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),G(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),G(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),N("millisecond","ms"),W("millisecond",16),Z("S",Jr,Rr),Z("SS",Jr,Ir),Z("SSS",Jr,Wr);var $a;for($a="SSSS";$a.length<=9;$a+="S")Z($a,Kr);for($a="S";$a.length<=9;$a+="S")re($a,Nn);var Xa=U("Milliseconds",!1);G("z",0,0,"zoneAbbr"),G("zz",0,0,"zoneName");var Qa=v.prototype;Qa.add=Ba,Qa.calendar=Kt,Qa.clone=$t,Qa.diff=rn,Qa.endOf=yn,Qa.format=dn,Qa.from=ln,Qa.fromNow=cn,Qa.to=_n,Qa.toNow=mn,Qa.get=V,Qa.invalidAt=Dn,Qa.isAfter=Xt,Qa.isBefore=Qt,Qa.isBetween=Zt,Qa.isSame=en,Qa.isSameOrAfter=tn,Qa.isSameOrBefore=nn,Qa.isValid=wn,Qa.lang=Ja,Qa.locale=hn,Qa.localeData=pn,Qa.max=Ia,Qa.min=Ra,Qa.parsingFlags=bn,Qa.set=J,Qa.startOf=fn,Qa.subtract=Va,Qa.toArray=Ln,Qa.toObject=Yn,Qa.toDate=gn,Qa.toISOString=sn,Qa.inspect=un,Qa.toJSON=kn,Qa.toString=on,Qa.unix=vn,Qa.valueOf=Mn,Qa.creationData=Tn,Qa.year=Ma,Qa.isLeapYear=ve,Qa.weekYear=xn,Qa.isoWeekYear=En,Qa.quarter=Qa.quarters=An,Qa.month=_e,Qa.daysInMonth=me,Qa.week=Qa.weeks=xe,Qa.isoWeek=Qa.isoWeeks=Ee,Qa.weeksInYear=Cn,Qa.isoWeeksInYear=jn,Qa.date=qa,Qa.day=Qa.days=Re,Qa.weekday=Ie,Qa.isoWeekday=We,Qa.dayOfYear=On,Qa.hour=Qa.hours=Sa,Qa.minute=Qa.minutes=Ga,Qa.second=Qa.seconds=Ka,Qa.millisecond=Qa.milliseconds=Xa,Qa.utcOffset=jt,Qa.utc=Pt,Qa.local=Ht,Qa.parseZone=At,Qa.hasAlignedHourOffset=Ot,Qa.isDST=Nt,Qa.isLocal=It,Qa.isUtcOffset=Wt,Qa.isUtc=Ft,Qa.isUTC=Ft,Qa.zoneAbbr=Rn,Qa.zoneName=In,Qa.dates=b("dates accessor is deprecated. Use date instead.",qa),Qa.months=b("months accessor is deprecated. Use month instead",_e),Qa.years=b("years accessor is deprecated. Use year instead",Ma),Qa.zone=b("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Ct),Qa.isDSTShifted=b("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Rt);var Za=E.prototype;Za.calendar=j,Za.longDateFormat=C,Za.invalidDate=P,Za.ordinal=H,Za.preparse=Un,Za.postformat=Un,Za.relativeTime=A,Za.pastFuture=O,Za.set=S,Za.months=se,Za.monthsShort=ue,Za.monthsParse=le,Za.monthsRegex=pe,Za.monthsShortRegex=he,Za.week=De,Za.firstDayOfYear=Se,Za.firstDayOfWeek=Te,Za.weekdays=Pe,Za.weekdaysMin=Ae,Za.weekdaysShort=He,Za.weekdaysParse=Ne,Za.weekdaysRegex=Fe,Za.weekdaysShortRegex=Ue,Za.weekdaysMinRegex=ze,Za.isPM=Ke,Za.meridiem=$e,et("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10,n=1===Y(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n}}),t.lang=b("moment.lang is deprecated. Use moment.locale instead.",et),t.langData=b("moment.langData is deprecated. Use moment.localeData instead.",rt);var ei=Math.abs,ti=sr("ms"),ni=sr("s"),ri=sr("m"),ai=sr("h"),ii=sr("d"),oi=sr("w"),si=sr("M"),ui=sr("y"),di=dr("milliseconds"),li=dr("seconds"),ci=dr("minutes"),_i=dr("hours"),mi=dr("days"),hi=dr("months"),pi=dr("years"),fi=Math.round,yi={s:45,m:45,h:22,d:26,M:11},Mi=Math.abs,vi=wt.prototype;return vi.abs=Xn,vi.add=Zn,vi.subtract=er,vi.as=ir,vi.asMilliseconds=ti,vi.asSeconds=ni,vi.asMinutes=ri,vi.asHours=ai,vi.asDays=ii,vi.asWeeks=oi,vi.asMonths=si,vi.asYears=ui,vi.valueOf=or,vi._bubble=nr,vi.get=ur,vi.milliseconds=di,vi.seconds=li,vi.minutes=ci,vi.hours=_i,vi.days=mi,vi.weeks=lr,vi.months=hi,vi.years=pi,vi.humanize=pr,vi.toISOString=fr,vi.toString=fr,vi.toJSON=fr,vi.locale=hn,vi.localeData=pn,vi.toIsoString=b("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",fr),vi.lang=Ja,G("X",0,0,"unix"),G("x",0,0,"valueOf"),Z("x",$r),Z("X",Zr),re("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),re("x",function(e,t,n){n._d=new Date(Y(e))}),t.version="2.17.1",r(gt),t.fn=Qa,t.min=Yt,t.max=kt,t.now=Wa,t.utc=_,t.unix=Wn,t.months=Jn,t.isDate=u,t.locale=et,t.invalid=f,t.duration=Ut,t.isMoment=g,t.weekdays=Gn,t.parseZone=Fn,t.localeData=rt,t.isDuration=bt,t.monthsShort=qn,t.weekdaysMin=$n,t.defineLocale=tt,t.updateLocale=nt,t.locales=at,t.weekdaysShort=Kn,t.normalizeUnits=R,t.relativeTimeRounding=mr,t.relativeTimeThreshold=hr,t.calendarFormat=Gt,t.prototype=Qa,t})}).call(t,n(335)(e))},function(e,t,n){"use strict";function r(e,t,n,r,i,o,s,u){if(a(t),!e){var d;if(void 0===t)d=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,i,o,s,u],c=0;d=new Error(t.replace(/%s/g,function(){return l[c++]})),d.name="Invariant Violation"}throw d.framesToPop=1,d}}var a=function(e){};e.exports=r},function(e,t,n){"use strict";var r=n(9),a=r;e.exports=a},function(e,t){"use strict";function n(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r=0&&v.splice(t,1)}function s(e){var t=document.createElement("style");return t.type="text/css",i(e,t),t}function u(e){var t=document.createElement("link");return t.rel="stylesheet",i(e,t),t}function d(e,t){var n,r,a;if(t.singleton){var i=M++;n=y||(y=s(t)),r=l.bind(null,n,i,!1),a=l.bind(null,n,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=u(t),r=_.bind(null,n),a=function(){o(n),n.href&&URL.revokeObjectURL(n.href)}):(n=s(t),r=c.bind(null,n),a=function(){o(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else a()}}function l(e,t,n,r){var a=n?"":r.css;if(e.styleSheet)e.styleSheet.cssText=g(t,a);else{var i=document.createTextNode(a),o=e.childNodes;o[t]&&e.removeChild(o[t]),o.length?e.insertBefore(i,o[t]):e.appendChild(i)}}function c(e,t){var n=t.css,r=t.media;if(r&&e.setAttribute("media",r),e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}function _(e,t){var n=t.css,r=t.sourceMap;r&&(n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+" */");var a=new Blob([n],{type:"text/css"}),i=e.href;e.href=URL.createObjectURL(a),i&&URL.revokeObjectURL(i)}var m={},h=function(e){var t;return function(){return"undefined"==typeof t&&(t=e.apply(this,arguments)),t}},p=h(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),f=h(function(){return document.head||document.getElementsByTagName("head")[0]}),y=null,M=0,v=[];e.exports=function(e,t){t=t||{},"undefined"==typeof t.singleton&&(t.singleton=p()),"undefined"==typeof t.insertAt&&(t.insertAt="bottom");var n=a(e);return r(n,t),function(e){for(var i=[],o=0;o1){for(var f=Array(p),y=0;y1){for(var v=Array(M),g=0;g]/;e.exports=r},function(e,t,n){"use strict";var r,a=n(7),i=n(38),o=/^[ \r\n\t\f]/,s=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,u=n(46),d=u(function(e,t){if(e.namespaceURI!==i.svg||"innerHTML"in e)e.innerHTML=t;else{r=r||document.createElement("div"),r.innerHTML=""+t+"";for(var n=r.firstChild;n.firstChild;)e.appendChild(n.firstChild)}});if(a.canUseDOM){var l=document.createElement("div");l.innerHTML=" ",""===l.innerHTML&&(d=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),o.test(t)||"<"===t[0]&&s.test(t)){e.innerHTML=String.fromCharCode(65279)+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t}),l=null}e.exports=d},function(e,t,n){(function(t){"use strict";function r(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function a(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(55):"undefined"!=typeof t&&(e=n(55)),e}var i=n(8),o=n(214),s=/^\)\]\}',?\n/,u={"Content-Type":"application/x-www-form-urlencoded"},d={adapter:a(),transformRequest:[function(e,t){return o(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e){e=e.replace(s,"");try{e=JSON.parse(e)}catch(e){}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};d.headers={common:{Accept:"application/json, text/plain, */*"}},i.forEach(["delete","get","head"],function(e){d.headers[e]={}}),i.forEach(["post","put","patch"],function(e){d.headers[e]=i.merge(u)}),e.exports=d}).call(t,n(36))},function(e,t){"use strict";function n(e,t){return e===t?0!==e||0!==t||1/e===1/t:e!==e&&t!==t}function r(e,t){if(n(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var r=Object.keys(e),i=Object.keys(t);if(r.length!==i.length)return!1;for(var o=0;o1)for(var n=1;n-1?void 0:o("96",e),!d.plugins[n]){t.extractEvents?void 0:o("97",e),d.plugins[n]=t;var r=t.eventTypes;for(var i in r)a(r[i],t,i)?void 0:o("98",i,e)}}}function a(e,t,n){d.eventNameDispatchConfigs.hasOwnProperty(n)?o("99",n):void 0,d.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var a in r)if(r.hasOwnProperty(a)){var s=r[a];i(s,t,n)}return!0}return!!e.registrationName&&(i(e.registrationName,t,n),!0)}function i(e,t,n){d.registrationNameModules[e]?o("100",e):void 0,d.registrationNameModules[e]=t,d.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var o=n(4),s=(n(2),null),u={},d={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},possibleRegistrationNames:null,injectEventPluginOrder:function(e){s?o("101"):void 0,s=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var t=!1;for(var n in e)if(e.hasOwnProperty(n)){var a=e[n];u.hasOwnProperty(n)&&u[n]===a||(u[n]?o("102",n):void 0,u[n]=a,t=!0)}t&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return d.registrationNameModules[t.registrationName]||null;if(void 0!==t.phasedRegistrationNames){var n=t.phasedRegistrationNames;for(var r in n)if(n.hasOwnProperty(r)){var a=d.registrationNameModules[n[r]];if(a)return a}}return null},_resetEventPlugins:function(){s=null;for(var e in u)u.hasOwnProperty(e)&&delete u[e];d.plugins.length=0;var t=d.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=d.registrationNameModules;for(var a in r)r.hasOwnProperty(a)&&delete r[a]}};e.exports=d},function(e,t,n){"use strict";function r(e){return"topMouseUp"===e||"topTouchEnd"===e||"topTouchCancel"===e}function a(e){return"topMouseMove"===e||"topTouchMove"===e}function i(e){return"topMouseDown"===e||"topTouchStart"===e}function o(e,t,n,r){var a=e.type||"unknown-event";e.currentTarget=y.getNodeFromInstance(r),t?p.invokeGuardedCallbackWithCatch(a,n,e):p.invokeGuardedCallback(a,n,e),e.currentTarget=null}function s(e,t){var n=e._dispatchListeners,r=e._dispatchInstances;if(Array.isArray(n))for(var a=0;a0&&r.length<20?n+" (keys: "+r.join(", ")+")":n}function i(e,t){var n=s.get(e);if(!n){return null}return n}var o=n(4),s=(n(13),n(27)),u=(n(10),n(11)),d=(n(2),n(3),{isMounted:function(e){var t=s.get(e);return!!t&&!!t._renderedComponent},enqueueCallback:function(e,t,n){d.validateCallback(t,n);var a=i(e);return a?(a._pendingCallbacks?a._pendingCallbacks.push(t):a._pendingCallbacks=[t],void r(a)):null},enqueueCallbackInternal:function(e,t){e._pendingCallbacks?e._pendingCallbacks.push(t):e._pendingCallbacks=[t],r(e)},enqueueForceUpdate:function(e){var t=i(e,"forceUpdate");t&&(t._pendingForceUpdate=!0,r(t))},enqueueReplaceState:function(e,t){var n=i(e,"replaceState");n&&(n._pendingStateQueue=[t],n._pendingReplaceState=!0,r(n))},enqueueSetState:function(e,t){var n=i(e,"setState");if(n){var a=n._pendingStateQueue||(n._pendingStateQueue=[]);a.push(t),r(n)}},enqueueElementInternal:function(e,t,n){e._pendingElement=t,e._context=n,r(e)},validateCallback:function(e,t){e&&"function"!=typeof e?o("122",t,a(e)):void 0}});e.exports=d},function(e,t){"use strict";var n=function(e){return"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(t,n,r,a){MSApp.execUnsafeLocalFunction(function(){return e(t,n,r,a)})}:e};e.exports=n},function(e,t){"use strict";function n(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}e.exports=n},function(e,t){"use strict";function n(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=a[e];return!!r&&!!n[r]}function r(e){return n}var a={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};e.exports=r},function(e,t){"use strict";function n(e){var t=e.target||e.srcElement||window;return t.correspondingUseElement&&(t=t.correspondingUseElement),3===t.nodeType?t.parentNode:t}e.exports=n},function(e,t,n){"use strict";function r(e,t){if(!i.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var o=document.createElement("div");o.setAttribute(n,"return;"),r="function"==typeof o[n]}return!r&&a&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var a,i=n(7);i.canUseDOM&&(a=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),e.exports=r},function(e,t){"use strict";function n(e,t){var n=null===e||e===!1,r=null===t||t===!1;if(n||r)return n===r;var a=typeof e,i=typeof t;return"string"===a||"number"===a?"string"===i||"number"===i:"object"===i&&e.type===t.type&&e.key===t.key}e.exports=n},function(e,t,n){"use strict";var r=(n(5),n(9)),a=(n(3),r);e.exports=a},function(e,t,n){"use strict";function r(e,t,n){this.props=e,this.context=t,this.refs=o,this.updater=n||i}var a=n(23),i=n(54),o=(n(195),n(24));n(2),n(3);r.prototype.isReactComponent={},r.prototype.setState=function(e,t){"object"!=typeof e&&"function"!=typeof e&&null!=e?a("85"):void 0,this.updater.enqueueSetState(this,e),t&&this.updater.enqueueCallback(this,t,"setState")},r.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this),e&&this.updater.enqueueCallback(this,e,"forceUpdate")};e.exports=r},function(e,t,n){"use strict";function r(e,t){}var a=(n(3),{isMounted:function(e){return!1},enqueueCallback:function(e,t){},enqueueForceUpdate:function(e){r(e,"forceUpdate")},enqueueReplaceState:function(e,t){r(e,"replaceState")},enqueueSetState:function(e,t){r(e,"setState")}});e.exports=a},function(e,t,n){"use strict";var r=n(8),a=n(206),i=n(209),o=n(215),s=n(213),u=n(58),d="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n(208);e.exports=function(e){return new Promise(function(t,l){var c=e.data,_=e.headers;r.isFormData(c)&&delete _["Content-Type"];var m=new XMLHttpRequest,h="onreadystatechange",p=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in m||s(e.url)||(m=new window.XDomainRequest,h="onload",p=!0,m.onprogress=function(){},m.ontimeout=function(){}),e.auth){var f=e.auth.username||"",y=e.auth.password||"";_.Authorization="Basic "+d(f+":"+y)}if(m.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),m.timeout=e.timeout,m[h]=function(){if(m&&(4===m.readyState||p)&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in m?o(m.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?m.response:m.responseText,i={data:r,status:1223===m.status?204:m.status,statusText:1223===m.status?"No Content":m.statusText,headers:n,config:e,request:m};a(t,l,i),m=null}},m.onerror=function(){l(u("Network Error",e)),m=null},m.ontimeout=function(){l(u("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED")),m=null},r.isStandardBrowserEnv()){var M=n(211),v=(e.withCredentials||s(e.url))&&e.xsrfCookieName?M.read(e.xsrfCookieName):void 0;v&&(_[e.xsrfHeaderName]=v)}if("setRequestHeader"in m&&r.forEach(_,function(e,t){"undefined"==typeof c&&"content-type"===t.toLowerCase()?delete _[t]:m.setRequestHeader(t,e)}),e.withCredentials&&(m.withCredentials=!0),e.responseType)try{m.responseType=e.responseType}catch(e){if("json"!==m.responseType)throw e}"function"==typeof e.onDownloadProgress&&m.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&m.upload&&m.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){m&&(m.abort(),l(e),m=null)}),void 0===c&&(c=null),m.send(c)})}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t,n){"use strict";var r=n(205);e.exports=function(e,t,n,a){var i=new Error(e);return r(i,t,n,a)}},function(e,t){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r=20?"ste":"de")},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ar-dz",{months:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"أح_إث_ثلا_أر_خم_جم_سب".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:0,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},n=function(e){return 0===e?0:1===e?1:2===e?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},r={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},a=function(e){return function(t,a,i,o){var s=n(t),u=r[e][n(t)];return 2===s&&(u=u[a?0:1]),u.replace(/%d/i,t)}},i=["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],o=e.defineLocale("ar-ly",{months:i,monthsShort:i,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,t,n){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:a("s"),m:a("m"),mm:a("m"),h:a("h"),hh:a("h"),d:a("d"),dd:a("d"),M:a("M"),MM:a("M"),y:a("y"),yy:a("y")},preparse:function(e){return e.replace(/\u200f/g,"").replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return o})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:6,doy:12}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},n={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},r=e.defineLocale("ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,t,n){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(e){return e.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return n[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},week:{dow:0,doy:6}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ar-tn",{months:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},n={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},r=function(e){return 0===e?0:1===e?1:2===e?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},a={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},i=function(e){return function(t,n,i,o){var s=r(t),u=a[e][r(t)];return 2===s&&(u=u[n?0:1]),u.replace(/%d/i,t)}},o=["كانون الثاني يناير","شباط فبراير","آذار مارس","نيسان أبريل","أيار مايو","حزيران يونيو","تموز يوليو","آب أغسطس","أيلول سبتمبر","تشرين الأول أكتوبر","تشرين الثاني نوفمبر","كانون الأول ديسمبر"],s=e.defineLocale("ar",{months:o,monthsShort:o,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,t,n){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:i("s"),m:i("m"),mm:i("m"),h:i("h"),hh:i("h"),d:i("d"),dd:i("d"),M:i("M"),MM:i("M"),y:i("y"),yy:i("y")},preparse:function(e){return e.replace(/\u200f/g,"").replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return n[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return s})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-üncü",4:"-üncü",100:"-üncü",6:"-ncı",9:"-uncu",10:"-uncu",30:"-uncu",60:"-ıncı",90:"-ıncı"},n=e.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),weekdaysShort:"Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"),weekdaysMin:"Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[gələn həftə] dddd [saat] LT",lastDay:"[dünən] LT",lastWeek:"[keçən həftə] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s əvvəl",s:"birneçə saniyyə",m:"bir dəqiqə",mm:"%d dəqiqə",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gecə|səhər|gündüz|axşam/,isPM:function(e){return/^(gündüz|axşam)$/.test(e)},meridiem:function(e,t,n){return e<4?"gecə":e<12?"səhər":e<17?"gündüz":"axşam"},ordinalParse:/\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,ordinal:function(e){if(0===e)return e+"-ıncı";var n=e%10,r=e%100-n,a=e>=100?100:null;return e+(t[n]||t[r]||t[a])},week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t){var n=e.split("_");return t%10===1&&t%100!==11?n[0]:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?n[1]:n[2]}function n(e,n,r){var a={mm:n?"хвіліна_хвіліны_хвілін":"хвіліну_хвіліны_хвілін",hh:n?"гадзіна_гадзіны_гадзін":"гадзіну_гадзіны_гадзін",dd:"дзень_дні_дзён",MM:"месяц_месяцы_месяцаў",yy:"год_гады_гадоў"};return"m"===r?n?"хвіліна":"хвіліну":"h"===r?n?"гадзіна":"гадзіну":e+" "+t(a[r],+e)}var r=e.defineLocale("be",{months:{format:"студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня".split("_"),standalone:"студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань".split("_")},monthsShort:"студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж".split("_"),weekdays:{format:"нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу".split("_"),standalone:"нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота".split("_"),isFormat:/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/},weekdaysShort:"нд_пн_ат_ср_чц_пт_сб".split("_"),weekdaysMin:"нд_пн_ат_ср_чц_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., HH:mm",LLLL:"dddd, D MMMM YYYY г., HH:mm"},calendar:{sameDay:"[Сёння ў] LT",nextDay:"[Заўтра ў] LT",lastDay:"[Учора ў] LT",nextWeek:function(){return"[У] dddd [ў] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[У мінулую] dddd [ў] LT";case 1:case 2:case 4:return"[У мінулы] dddd [ў] LT"}},sameElse:"L"},relativeTime:{future:"праз %s",past:"%s таму",s:"некалькі секунд",m:n,mm:n,h:n,hh:n,d:"дзень",dd:n,M:"месяц",MM:n,y:"год",yy:n},meridiemParse:/ночы|раніцы|дня|вечара/,isPM:function(e){return/^(дня|вечара)$/.test(e)},meridiem:function(e,t,n){return e<4?"ночы":e<12?"раніцы":e<17?"дня":"вечара"},ordinalParse:/\d{1,2}-(і|ы|га)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":case"w":case"W":return e%10!==2&&e%10!==3||e%100===12||e%100===13?e+"-ы":e+"-і";case"D":return e+"-га";default:return e}},week:{dow:1,doy:7}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("bg",{months:"януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),monthsShort:"янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),weekdays:"неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),weekdaysShort:"нед_пон_вто_сря_чет_пет_съб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Днес в] LT",nextDay:"[Утре в] LT",nextWeek:"dddd [в] LT",lastDay:"[Вчера в] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[В изминалата] dddd [в] LT";case 1:case 2:case 4:case 5:return"[В изминалия] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"след %s",past:"преди %s",s:"няколко секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дни",M:"месец",MM:"%d месеца",y:"година",yy:"%d години"},ordinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(e){var t=e%10,n=e%100;return 0===e?e+"-ев":0===n?e+"-ен":n>10&&n<20?e+"-ти":1===t?e+"-ви":2===t?e+"-ри":7===t||8===t?e+"-ми":e+"-ти"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"১",2:"২",3:"৩",4:"৪",5:"৫",6:"৬",7:"৭",8:"৮",9:"৯",0:"০"},n={"১":"1","২":"2","৩":"3","৪":"4","৫":"5","৬":"6","৭":"7","৮":"8","৯":"9","০":"0"},r=e.defineLocale("bn",{months:"জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর".split("_"),monthsShort:"জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে".split("_"),weekdays:"রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার".split("_"),weekdaysShort:"রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি".split("_"),weekdaysMin:"রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি".split("_"),longDateFormat:{LT:"A h:mm সময়",LTS:"A h:mm:ss সময়",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm সময়",LLLL:"dddd, D MMMM YYYY, A h:mm সময়"},calendar:{sameDay:"[আজ] LT",nextDay:"[আগামীকাল] LT",nextWeek:"dddd, LT",lastDay:"[গতকাল] LT",lastWeek:"[গত] dddd, LT",sameElse:"L"},relativeTime:{future:"%s পরে",past:"%s আগে",s:"কয়েক সেকেন্ড",m:"এক মিনিট",mm:"%d মিনিট",h:"এক ঘন্টা",hh:"%d ঘন্টা",d:"এক দিন",dd:"%d দিন",M:"এক মাস",MM:"%d মাস",y:"এক বছর",yy:"%d বছর"},preparse:function(e){return e.replace(/[১২৩৪৫৬৭৮৯০]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/রাত|সকাল|দুপুর|বিকাল|রাত/,meridiemHour:function(e,t){return 12===e&&(e=0),"রাত"===t&&e>=4||"দুপুর"===t&&e<5||"বিকাল"===t?e+12:e},meridiem:function(e,t,n){return e<4?"রাত":e<10?"সকাল":e<17?"দুপুর":e<20?"বিকাল":"রাত"},week:{dow:0,doy:6}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"༡",2:"༢",3:"༣",4:"༤",5:"༥",6:"༦",7:"༧",8:"༨",9:"༩",0:"༠"},n={"༡":"1","༢":"2","༣":"3","༤":"4","༥":"5","༦":"6","༧":"7","༨":"8","༩":"9","༠":"0"},r=e.defineLocale("bo",{months:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),monthsShort:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),weekdays:"གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་".split("_"),weekdaysShort:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),weekdaysMin:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[དི་རིང] LT",nextDay:"[སང་ཉིན] LT",nextWeek:"[བདུན་ཕྲག་རྗེས་མ], LT",lastDay:"[ཁ་སང] LT",lastWeek:"[བདུན་ཕྲག་མཐའ་མ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ལ་",past:"%s སྔན་ལ",s:"ལམ་སང",m:"སྐར་མ་གཅིག",mm:"%d སྐར་མ",h:"ཆུ་ཚོད་གཅིག",hh:"%d ཆུ་ཚོད",d:"ཉིན་གཅིག",dd:"%d ཉིན་",M:"ཟླ་བ་གཅིག",MM:"%d ཟླ་བ",y:"ལོ་གཅིག",yy:"%d ལོ"},preparse:function(e){return e.replace(/[༡༢༣༤༥༦༧༨༩༠]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,meridiemHour:function(e,t){return 12===e&&(e=0),"མཚན་མོ"===t&&e>=4||"ཉིན་གུང"===t&&e<5||"དགོང་དག"===t?e+12:e},meridiem:function(e,t,n){return e<4?"མཚན་མོ":e<10?"ཞོགས་ཀས":e<17?"ཉིན་གུང":e<20?"དགོང་དག":"མཚན་མོ"},week:{dow:0,doy:6}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n){var r={mm:"munutenn",MM:"miz",dd:"devezh"};return e+" "+a(r[n],e)}function n(e){switch(r(e)){case 1:case 3:case 4:case 5:case 9:return e+" bloaz";default:return e+" vloaz"}}function r(e){return e>9?r(e%10):e}function a(e,t){return 2===t?i(e):e}function i(e){var t={m:"v",b:"v",d:"z"};return void 0===t[e.charAt(0)]?e:t[e.charAt(0)]+e.substring(1)}var o=e.defineLocale("br",{months:"Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h[e]mm A",LTS:"h[e]mm:ss A",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY h[e]mm A",LLLL:"dddd, D [a viz] MMMM YYYY h[e]mm A"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warc'hoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Dec'h da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s 'zo",s:"un nebeud segondennoù",m:"ur vunutenn",mm:t,h:"un eur",hh:"%d eur",d:"un devezh",dd:t,M:"ur miz",MM:t,y:"ur bloaz",yy:n},ordinalParse:/\d{1,2}(añ|vet)/,ordinal:function(e){var t=1===e?"añ":"vet";return e+t},week:{dow:1,doy:4}});return o})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n){var r=e+" ";switch(n){case"m":return t?"jedna minuta":"jedne minute";case"mm":return r+=1===e?"minuta":2===e||3===e||4===e?"minute":"minuta";case"h":return t?"jedan sat":"jednog sata";case"hh":return r+=1===e?"sat":2===e||3===e||4===e?"sata":"sati";case"dd":return r+=1===e?"dan":"dana";case"MM":return r+=1===e?"mjesec":2===e||3===e||4===e?"mjeseca":"mjeseci";case"yy":return r+=1===e?"godina":2===e||3===e||4===e?"godine":"godina"}}var n=e.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:t,mm:t,h:t,hh:t,d:"dan",dd:t,M:"mjesec",MM:t,y:"godinu",yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ca",{months:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),monthsShort:"gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd D MMMM YYYY H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"d'aquí %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(e,t){var n=1===e?"r":2===e?"n":3===e?"r":4===e?"t":"è";return"w"!==t&&"W"!==t||(n="a"),e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e){return e>1&&e<5&&1!==~~(e/10)}function n(e,n,r,a){var i=e+" ";switch(r){case"s":return n||a?"pár sekund":"pár sekundami";case"m":return n?"minuta":a?"minutu":"minutou";case"mm":return n||a?i+(t(e)?"minuty":"minut"):i+"minutami";case"h":return n?"hodina":a?"hodinu":"hodinou";case"hh":return n||a?i+(t(e)?"hodiny":"hodin"):i+"hodinami";case"d":return n||a?"den":"dnem";case"dd":return n||a?i+(t(e)?"dny":"dní"):i+"dny";case"M":return n||a?"měsíc":"měsícem";case"MM":return n||a?i+(t(e)?"měsíce":"měsíců"):i+"měsíci";case"y":return n||a?"rok":"rokem";case"yy":return n||a?i+(t(e)?"roky":"let"):i+"lety"}}var r="leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),a="led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_"),i=e.defineLocale("cs",{months:r,monthsShort:a,monthsParse:function(e,t){var n,r=[];for(n=0;n<12;n++)r[n]=new RegExp("^"+e[n]+"$|^"+t[n]+"$","i");return r}(r,a),shortMonthsParse:function(e){var t,n=[];for(t=0;t<12;t++)n[t]=new RegExp("^"+e[t]+"$","i");return n}(a),longMonthsParse:function(e){var t,n=[];for(t=0;t<12;t++)n[t]=new RegExp("^"+e[t]+"$","i");return n}(r),weekdays:"neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),weekdaysShort:"ne_po_út_st_čt_pá_so".split("_"),weekdaysMin:"ne_po_út_st_čt_pá_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[zítra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v neděli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve středu v] LT";case 4:return"[ve čtvrtek v] LT";case 5:return"[v pátek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[včera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou neděli v] LT";case 1:case 2:return"[minulé] dddd [v] LT";case 3:return"[minulou středu v] LT";case 4:case 5:return"[minulý] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"před %s",s:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("cv",{months:"кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав".split("_"),monthsShort:"кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш".split("_"),weekdays:"вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун".split("_"),weekdaysShort:"выр_тун_ытл_юн_кӗҫ_эрн_шӑм".split("_"),weekdaysMin:"вр_тн_ыт_юн_кҫ_эр_шм".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]",LLL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm",LLLL:"dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm"},calendar:{sameDay:"[Паян] LT [сехетре]",nextDay:"[Ыран] LT [сехетре]",lastDay:"[Ӗнер] LT [сехетре]",nextWeek:"[Ҫитес] dddd LT [сехетре]",lastWeek:"[Иртнӗ] dddd LT [сехетре]",sameElse:"L"},relativeTime:{future:function(e){var t=/сехет$/i.exec(e)?"рен":/ҫул$/i.exec(e)?"тан":"ран";return e+t},past:"%s каялла",s:"пӗр-ик ҫеккунт",m:"пӗр минут",mm:"%d минут",h:"пӗр сехет",hh:"%d сехет",d:"пӗр кун",dd:"%d кун",M:"пӗр уйӑх",MM:"%d уйӑх",y:"пӗр ҫул",yy:"%d ҫул"},ordinalParse:/\d{1,2}-мӗш/,ordinal:"%d-мӗш",week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("cy",{months:"Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),monthsShort:"Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),weekdays:"Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),weekdaysShort:"Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),weekdaysMin:"Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Heddiw am] LT",nextDay:"[Yfory am] LT",nextWeek:"dddd [am] LT",lastDay:"[Ddoe am] LT",lastWeek:"dddd [diwethaf am] LT",sameElse:"L"},relativeTime:{future:"mewn %s",past:"%s yn ôl",s:"ychydig eiliadau",m:"munud",mm:"%d munud",h:"awr",hh:"%d awr",d:"diwrnod",dd:"%d diwrnod",M:"mis",MM:"%d mis",y:"blwyddyn",yy:"%d flynedd"},ordinalParse:/\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,ordinal:function(e){var t=e,n="",r=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"];return t>20?n=40===t||50===t||60===t||80===t||100===t?"fed":"ain":t>0&&(n=r[t]),e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY HH:mm"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I går kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return t?a[n][0]:a[n][1]}var n=e.defineLocale("de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,M:t,MM:t,y:t,yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return t?a[n][0]:a[n][1]}var n=e.defineLocale("de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,M:t,MM:t,y:t,yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=["ޖެނުއަރީ","ފެބްރުއަރީ","މާރިޗު","އޭޕްރީލު","މޭ","ޖޫން","ޖުލައި","އޯގަސްޓު","ސެޕްޓެމްބަރު","އޮކްޓޯބަރު","ނޮވެމްބަރު","ޑިސެމްބަރު"],n=["އާދިއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"],r=e.defineLocale("dv",{months:t,monthsShort:t,weekdays:n,weekdaysShort:n,weekdaysMin:"އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/މކ|މފ/,isPM:function(e){return"މފ"===e},meridiem:function(e,t,n){return e<12?"މކ":"މފ"},calendar:{sameDay:"[މިއަދު] LT",nextDay:"[މާދަމާ] LT",nextWeek:"dddd LT",lastDay:"[އިއްޔެ] LT",lastWeek:"[ފާއިތުވި] dddd LT",sameElse:"L"},relativeTime:{future:"ތެރޭގައި %s",past:"ކުރިން %s",s:"ސިކުންތުކޮޅެއް",m:"މިނިޓެއް",mm:"މިނިޓު %d",h:"ގަޑިއިރެއް",hh:"ގަޑިއިރު %d", +d:"ދުވަހެއް",dd:"ދުވަސް %d",M:"މަހެއް",MM:"މަސް %d",y:"އަހަރެއް",yy:"އަހަރު %d"},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:7,doy:12}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e){return e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}var n=e.defineLocale("el",{monthsNominativeEl:"Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),monthsGenitiveEl:"Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),months:function(e,t){return/D/.test(t.substring(0,t.indexOf("MMMM")))?this._monthsGenitiveEl[e.month()]:this._monthsNominativeEl[e.month()]},monthsShort:"Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),weekdays:"Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),weekdaysShort:"Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),weekdaysMin:"Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),meridiem:function(e,t,n){return e>11?n?"μμ":"ΜΜ":n?"πμ":"ΠΜ"},isPM:function(e){return"μ"===(e+"").toLowerCase()[0]},meridiemParse:/[ΠΜ]\.?Μ?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[Σήμερα {}] LT",nextDay:"[Αύριο {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[Χθες {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[το προηγούμενο] dddd [{}] LT";default:return"[την προηγούμενη] dddd [{}] LT"}},sameElse:"L"},calendar:function(e,n){var r=this._calendarEl[e],a=n&&n.hours();return t(r)&&(r=r.apply(n)),r.replace("{}",a%12===1?"στη":"στις")},relativeTime:{future:"σε %s",past:"%s πριν",s:"λίγα δευτερόλεπτα",m:"ένα λεπτό",mm:"%d λεπτά",h:"μία ώρα",hh:"%d ώρες",d:"μία μέρα",dd:"%d μέρες",M:"ένας μήνας",MM:"%d μήνες",y:"ένας χρόνος",yy:"%d χρόνια"},ordinalParse:/\d{1,2}η/,ordinal:"%dη",week:{dow:1,doy:4}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec".split("_"),weekdays:"Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato".split("_"),weekdaysShort:"Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Ĵa_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D[-an de] MMMM, YYYY",LLL:"D[-an de] MMMM, YYYY HH:mm",LLLL:"dddd, [la] D[-an de] MMMM, YYYY HH:mm"},meridiemParse:/[ap]\.t\.m/i,isPM:function(e){return"p"===e.charAt(0).toLowerCase()},meridiem:function(e,t,n){return e>11?n?"p.t.m.":"P.T.M.":n?"a.t.m.":"A.T.M."},calendar:{sameDay:"[Hodiaŭ je] LT",nextDay:"[Morgaŭ je] LT",nextWeek:"dddd [je] LT",lastDay:"[Hieraŭ je] LT",lastWeek:"[pasinta] dddd [je] LT",sameElse:"L"},relativeTime:{future:"je %s",past:"antaŭ %s",s:"sekundoj",m:"minuto",mm:"%d minutoj",h:"horo",hh:"%d horoj",d:"tago",dd:"%d tagoj",M:"monato",MM:"%d monatoj",y:"jaro",yy:"%d jaroj"},ordinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),n="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),r=e.defineLocale("es-do",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,r){return/-MMM-/.test(r)?n[e.month()]:t[e.month()]},monthsParseExact:!0,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),n="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),r=e.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,r){return/-MMM-/.test(r)?n[e.month()]:t[e.month()]},monthsParseExact:!0,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a={s:["mõne sekundi","mõni sekund","paar sekundit"],m:["ühe minuti","üks minut"],mm:[e+" minuti",e+" minutit"],h:["ühe tunni","tund aega","üks tund"],hh:[e+" tunni",e+" tundi"],d:["ühe päeva","üks päev"],M:["kuu aja","kuu aega","üks kuu"],MM:[e+" kuu",e+" kuud"],y:["ühe aasta","aasta","üks aasta"],yy:[e+" aasta",e+" aastat"]};return t?a[n][2]?a[n][2]:a[n][1]:r?a[n][0]:a[n][1]}var n=e.defineLocale("et",{months:"jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[Täna,] LT",nextDay:"[Homme,] LT",nextWeek:"[Järgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s pärast",past:"%s tagasi",s:t,m:t,mm:t,h:t,hh:t,d:t,dd:"%d päeva",M:t,MM:t,y:t,yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("eu",{months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),monthsParseExact:!0,weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY[ko] MMMM[ren] D[a]",LLL:"YYYY[ko] MMMM[ren] D[a] HH:mm",LLLL:"dddd, YYYY[ko] MMMM[ren] D[a] HH:mm",l:"YYYY-M-D",ll:"YYYY[ko] MMM D[a]",lll:"YYYY[ko] MMM D[a] HH:mm",llll:"ddd, YYYY[ko] MMM D[a] HH:mm"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},n={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},r=e.defineLocale("fa",{months:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysShort:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(e){return/بعد از ظهر/.test(e)},meridiem:function(e,t,n){return e<12?"قبل از ظهر":"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چندین ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(e){return e.replace(/[۰-۹]/g,function(e){return n[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},ordinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,r,a){var i="";switch(r){case"s":return a?"muutaman sekunnin":"muutama sekunti";case"m":return a?"minuutin":"minuutti";case"mm":i=a?"minuutin":"minuuttia";break;case"h":return a?"tunnin":"tunti";case"hh":i=a?"tunnin":"tuntia";break;case"d":return a?"päivän":"päivä";case"dd":i=a?"päivän":"päivää";break;case"M":return a?"kuukauden":"kuukausi";case"MM":i=a?"kuukauden":"kuukautta";break;case"y":return a?"vuoden":"vuosi";case"yy":i=a?"vuoden":"vuotta"}return i=n(e,a)+" "+i}function n(e,t){return e<10?t?a[e]:r[e]:e}var r="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),a=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",r[7],r[8],r[9]],i=e.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("fo",{months:"januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"),weekdaysShort:"sun_mán_týs_mik_hós_frí_ley".split("_"),weekdaysMin:"su_má_tý_mi_hó_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D. MMMM, YYYY HH:mm"},calendar:{sameDay:"[Í dag kl.] LT",nextDay:"[Í morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[Í gjár kl.] LT",lastWeek:"[síðstu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s síðani",s:"fá sekund",m:"ein minutt",mm:"%d minuttir",h:"ein tími",hh:"%d tímar",d:"ein dagur",dd:"%d dagar",M:"ein mánaði",MM:"%d mánaðir",y:"eitt ár",yy:"%d ár"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(e){return e+(1===e?"er":"e")}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("fr-ch",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(e){return e+(1===e?"er":"e")},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(e){return e+(1===e?"er":"")},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t="jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.".split("_"),n="jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),r=e.defineLocale("fy",{months:"jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber".split("_"),monthsShort:function(e,r){return/-MMM-/.test(r)?n[e.month()]:t[e.month()]},monthsParseExact:!0,weekdays:"snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon".split("_"),weekdaysShort:"si._mo._ti._wo._to._fr._so.".split("_"),weekdaysMin:"Si_Mo_Ti_Wo_To_Fr_So".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[hjoed om] LT",nextDay:"[moarn om] LT",nextWeek:"dddd [om] LT",lastDay:"[juster om] LT",lastWeek:"[ôfrûne] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oer %s",past:"%s lyn",s:"in pear sekonden",m:"ien minút",mm:"%d minuten",h:"ien oere",hh:"%d oeren",d:"ien dei",dd:"%d dagen",M:"ien moanne",MM:"%d moannen",y:"ien jier",yy:"%d jierren"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=["Am Faoilleach","An Gearran","Am Màrt","An Giblean","An Cèitean","An t-Ògmhios","An t-Iuchar","An Lùnastal","An t-Sultain","An Dàmhair","An t-Samhain","An Dùbhlachd"],n=["Faoi","Gear","Màrt","Gibl","Cèit","Ògmh","Iuch","Lùn","Sult","Dàmh","Samh","Dùbh"],r=["Didòmhnaich","Diluain","Dimàirt","Diciadain","Diardaoin","Dihaoine","Disathairne"],a=["Did","Dil","Dim","Dic","Dia","Dih","Dis"],i=["Dò","Lu","Mà","Ci","Ar","Ha","Sa"],o=e.defineLocale("gd",{months:t,monthsShort:n,monthsParseExact:!0,weekdays:r,weekdaysShort:a,weekdaysMin:i,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[An-diugh aig] LT",nextDay:"[A-màireach aig] LT",nextWeek:"dddd [aig] LT",lastDay:"[An-dè aig] LT",lastWeek:"dddd [seo chaidh] [aig] LT",sameElse:"L"},relativeTime:{future:"ann an %s",past:"bho chionn %s",s:"beagan diogan",m:"mionaid",mm:"%d mionaidean",h:"uair",hh:"%d uairean",d:"latha",dd:"%d latha",M:"mìos",MM:"%d mìosan",y:"bliadhna",yy:"%d bliadhna"},ordinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(e){var t=1===e?"d":e%10===2?"na":"mh";return e+t},week:{dow:1,doy:4}});return o})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("gl",{months:"xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro".split("_"),monthsShort:"xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"domingo_luns_martes_mércores_xoves_venres_sábado".split("_"),weekdaysShort:"dom._lun._mar._mér._xov._ven._sáb.".split("_"),weekdaysMin:"do_lu_ma_mé_xo_ve_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"ás":"á")+"] LT"},nextDay:function(){return"[mañá "+(1!==this.hours()?"ás":"á")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"ás":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"á":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"ás":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(e){return 0===e.indexOf("un")?"n"+e:"en "+e},past:"hai %s",s:"uns segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),weekdaysShort:"א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY HH:mm",LLLL:"dddd, D [ב]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(e){return 2===e?"שעתיים":e+" שעות"},d:"יום",dd:function(e){return 2===e?"יומיים":e+" ימים"},M:"חודש",MM:function(e){return 2===e?"חודשיים":e+" חודשים"},y:"שנה",yy:function(e){return 2===e?"שנתיים":e%10===0&&10!==e?e+" שנה":e+" שנים"}},meridiemParse:/אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,isPM:function(e){return/^(אחה"צ|אחרי הצהריים|בערב)$/.test(e)},meridiem:function(e,t,n){return e<5?"לפנות בוקר":e<10?"בבוקר":e<12?n?'לפנה"צ':"לפני הצהריים":e<18?n?'אחה"צ':"אחרי הצהריים":"בערב"}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},n={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},r=e.defineLocale("hi",{months:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),monthsParseExact:!0,weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm बजे",LLLL:"dddd, D MMMM YYYY, A h:mm बजे"},calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(e,t){return 12===e&&(e=0),"रात"===t?e<4?e:e+12:"सुबह"===t?e:"दोपहर"===t?e>=10?e:e+12:"शाम"===t?e+12:void 0},meridiem:function(e,t,n){return e<4?"रात":e<10?"सुबह":e<17?"दोपहर":e<20?"शाम":"रात"},week:{dow:0,doy:6}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n){var r=e+" ";switch(n){case"m":return t?"jedna minuta":"jedne minute";case"mm":return r+=1===e?"minuta":2===e||3===e||4===e?"minute":"minuta";case"h":return t?"jedan sat":"jednog sata";case"hh":return r+=1===e?"sat":2===e||3===e||4===e?"sata":"sati";case"dd":return r+=1===e?"dan":"dana";case"MM":return r+=1===e?"mjesec":2===e||3===e||4===e?"mjeseca":"mjeseci";case"yy":return r+=1===e?"godina":2===e||3===e||4===e?"godine":"godina"}}var n=e.defineLocale("hr",{months:{format:"siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:t,mm:t,h:t,hh:t,d:"dan",dd:t,M:"mjesec",MM:t,y:"godinu",yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a=e;switch(n){case"s":return r||t?"néhány másodperc":"néhány másodperce";case"m":return"egy"+(r||t?" perc":" perce");case"mm":return a+(r||t?" perc":" perce");case"h":return"egy"+(r||t?" óra":" órája");case"hh":return a+(r||t?" óra":" órája");case"d":return"egy"+(r||t?" nap":" napja");case"dd":return a+(r||t?" nap":" napja");case"M":return"egy"+(r||t?" hónap":" hónapja");case"MM":return a+(r||t?" hónap":" hónapja");case"y":return"egy"+(r||t?" év":" éve");case"yy":return a+(r||t?" év":" éve")}return""}function n(e){return(e?"":"[múlt] ")+"["+r[this.day()]+"] LT[-kor]"}var r="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" "),a=e.defineLocale("hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(e){return"u"===e.charAt(1).toLowerCase(); +},meridiem:function(e,t,n){return e<12?n===!0?"de":"DE":n===!0?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return n.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return n.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return a})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("hy-am",{months:{format:"հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի".split("_"),standalone:"հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր".split("_")},monthsShort:"հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ".split("_"),weekdays:"կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ".split("_"),weekdaysShort:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),weekdaysMin:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY թ.",LLL:"D MMMM YYYY թ., HH:mm",LLLL:"dddd, D MMMM YYYY թ., HH:mm"},calendar:{sameDay:"[այսօր] LT",nextDay:"[վաղը] LT",lastDay:"[երեկ] LT",nextWeek:function(){return"dddd [օրը ժամը] LT"},lastWeek:function(){return"[անցած] dddd [օրը ժամը] LT"},sameElse:"L"},relativeTime:{future:"%s հետո",past:"%s առաջ",s:"մի քանի վայրկյան",m:"րոպե",mm:"%d րոպե",h:"ժամ",hh:"%d ժամ",d:"օր",dd:"%d օր",M:"ամիս",MM:"%d ամիս",y:"տարի",yy:"%d տարի"},meridiemParse:/գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,isPM:function(e){return/^(ցերեկվա|երեկոյան)$/.test(e)},meridiem:function(e){return e<4?"գիշերվա":e<12?"առավոտվա":e<17?"ցերեկվա":"երեկոյան"},ordinalParse:/\d{1,2}|\d{1,2}-(ին|րդ)/,ordinal:function(e,t){switch(t){case"DDD":case"w":case"W":case"DDDo":return 1===e?e+"-ին":e+"-րդ";default:return e}},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(e,t){return 12===e&&(e=0),"pagi"===t?e:"siang"===t?e>=11?e:e+12:"sore"===t||"malam"===t?e+12:void 0},meridiem:function(e,t,n){return e<11?"pagi":e<15?"siang":e<19?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e){return e%100===11||e%10!==1}function n(e,n,r,a){var i=e+" ";switch(r){case"s":return n||a?"nokkrar sekúndur":"nokkrum sekúndum";case"m":return n?"mínúta":"mínútu";case"mm":return t(e)?i+(n||a?"mínútur":"mínútum"):n?i+"mínúta":i+"mínútu";case"hh":return t(e)?i+(n||a?"klukkustundir":"klukkustundum"):i+"klukkustund";case"d":return n?"dagur":a?"dag":"degi";case"dd":return t(e)?n?i+"dagar":i+(a?"daga":"dögum"):n?i+"dagur":i+(a?"dag":"degi");case"M":return n?"mánuður":a?"mánuð":"mánuði";case"MM":return t(e)?n?i+"mánuðir":i+(a?"mánuði":"mánuðum"):n?i+"mánuður":i+(a?"mánuð":"mánuði");case"y":return n||a?"ár":"ári";case"yy":return t(e)?i+(n||a?"ár":"árum"):i+(n||a?"ár":"ári")}}var r=e.defineLocale("is",{months:"janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),monthsShort:"jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),weekdays:"sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),weekdaysShort:"sun_mán_þri_mið_fim_fös_lau".split("_"),weekdaysMin:"Su_Má_Þr_Mi_Fi_Fö_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[í dag kl.] LT",nextDay:"[á morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[í gær kl.] LT",lastWeek:"[síðasta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s síðan",s:n,m:n,mm:n,h:"klukkustund",hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"Do_Lu_Ma_Me_Gi_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(e){return(/^[0-9].+$/.test(e)?"tra":"in")+" "+e},past:"%s fa",s:"alcuni secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ja",{months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"Ah時m分",LTS:"Ah時m分s秒",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah時m分",LLLL:"YYYY年M月D日Ah時m分 dddd"},meridiemParse:/午前|午後/i,isPM:function(e){return"午後"===e},meridiem:function(e,t,n){return e<12?"午前":"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:"[来週]dddd LT",lastDay:"[昨日] LT",lastWeek:"[前週]dddd LT",sameElse:"L"},ordinalParse:/\d{1,2}日/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";default:return e}},relativeTime:{future:"%s後",past:"%s前",s:"数秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("jv",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des".split("_"),weekdays:"Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu".split("_"),weekdaysShort:"Min_Sen_Sel_Reb_Kem_Jem_Sep".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sp".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/enjing|siyang|sonten|ndalu/,meridiemHour:function(e,t){return 12===e&&(e=0),"enjing"===t?e:"siyang"===t?e>=11?e:e+12:"sonten"===t||"ndalu"===t?e+12:void 0},meridiem:function(e,t,n){return e<11?"enjing":e<15?"siyang":e<19?"sonten":"ndalu"},calendar:{sameDay:"[Dinten puniko pukul] LT",nextDay:"[Mbenjang pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kala wingi pukul] LT",lastWeek:"dddd [kepengker pukul] LT",sameElse:"L"},relativeTime:{future:"wonten ing %s",past:"%s ingkang kepengker",s:"sawetawis detik",m:"setunggal menit",mm:"%d menit",h:"setunggal jam",hh:"%d jam",d:"sedinten",dd:"%d dinten",M:"sewulan",MM:"%d wulan",y:"setaun",yy:"%d taun"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ka",{months:{standalone:"იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი".split("_"),format:"იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს".split("_")},monthsShort:"იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),weekdays:{standalone:"კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი".split("_"),format:"კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს".split("_"),isFormat:/(წინა|შემდეგ)/},weekdaysShort:"კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"),weekdaysMin:"კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[დღეს] LT[-ზე]",nextDay:"[ხვალ] LT[-ზე]",lastDay:"[გუშინ] LT[-ზე]",nextWeek:"[შემდეგ] dddd LT[-ზე]",lastWeek:"[წინა] dddd LT-ზე",sameElse:"L"},relativeTime:{future:function(e){return/(წამი|წუთი|საათი|წელი)/.test(e)?e.replace(/ი$/,"ში"):e+"ში"},past:function(e){return/(წამი|წუთი|საათი|დღე|თვე)/.test(e)?e.replace(/(ი|ე)$/,"ის წინ"):/წელი/.test(e)?e.replace(/წელი$/,"წლის წინ"):void 0},s:"რამდენიმე წამი",m:"წუთი",mm:"%d წუთი",h:"საათი",hh:"%d საათი",d:"დღე",dd:"%d დღე",M:"თვე",MM:"%d თვე",y:"წელი",yy:"%d წელი"},ordinalParse:/0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,ordinal:function(e){return 0===e?e:1===e?e+"-ლი":e<20||e<=100&&e%20===0||e%100===0?"მე-"+e:e+"-ე"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={0:"-ші",1:"-ші",2:"-ші",3:"-ші",4:"-ші",5:"-ші",6:"-шы",7:"-ші",8:"-ші",9:"-шы",10:"-шы",20:"-шы",30:"-шы",40:"-шы",50:"-ші",60:"-шы",70:"-ші",80:"-ші",90:"-шы",100:"-ші"},n=e.defineLocale("kk",{months:"қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан".split("_"),monthsShort:"қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел".split("_"),weekdays:"жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі".split("_"),weekdaysShort:"жек_дүй_сей_сәр_бей_жұм_сен".split("_"),weekdaysMin:"жк_дй_сй_ср_бй_жм_сн".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Бүгін сағат] LT",nextDay:"[Ертең сағат] LT",nextWeek:"dddd [сағат] LT",lastDay:"[Кеше сағат] LT",lastWeek:"[Өткен аптаның] dddd [сағат] LT",sameElse:"L"},relativeTime:{future:"%s ішінде",past:"%s бұрын",s:"бірнеше секунд",m:"бір минут",mm:"%d минут",h:"бір сағат",hh:"%d сағат",d:"бір күн",dd:"%d күн",M:"бір ай",MM:"%d ай",y:"бір жыл",yy:"%d жыл"},ordinalParse:/\d{1,2}-(ші|шы)/,ordinal:function(e){var n=e%10,r=e>=100?100:null;return e+(t[e]||t[n]||t[r])},week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("km",{months:"មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),monthsShort:"មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),weekdays:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),weekdaysShort:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),weekdaysMin:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[ថ្ងៃនេះ ម៉ោង] LT",nextDay:"[ស្អែក ម៉ោង] LT",nextWeek:"dddd [ម៉ោង] LT",lastDay:"[ម្សិលមិញ ម៉ោង] LT",lastWeek:"dddd [សប្តាហ៍មុន] [ម៉ោង] LT",sameElse:"L"},relativeTime:{future:"%sទៀត",past:"%sមុន",s:"ប៉ុន្មានវិនាទី",m:"មួយនាទី",mm:"%d នាទី",h:"មួយម៉ោង",hh:"%d ម៉ោង",d:"មួយថ្ងៃ",dd:"%d ថ្ងៃ",M:"មួយខែ",MM:"%d ខែ",y:"មួយឆ្នាំ",yy:"%d ឆ្នាំ"},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ko",{months:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),monthsShort:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),weekdays:"일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),weekdaysShort:"일_월_화_수_목_금_토".split("_"),weekdaysMin:"일_월_화_수_목_금_토".split("_"),longDateFormat:{LT:"A h시 m분",LTS:"A h시 m분 s초",L:"YYYY.MM.DD",LL:"YYYY년 MMMM D일",LLL:"YYYY년 MMMM D일 A h시 m분",LLLL:"YYYY년 MMMM D일 dddd A h시 m분"},calendar:{sameDay:"오늘 LT",nextDay:"내일 LT",nextWeek:"dddd LT",lastDay:"어제 LT",lastWeek:"지난주 dddd LT",sameElse:"L"},relativeTime:{future:"%s 후",past:"%s 전",s:"몇 초",ss:"%d초",m:"일분",mm:"%d분",h:"한 시간",hh:"%d시간",d:"하루",dd:"%d일",M:"한 달",MM:"%d달",y:"일 년",yy:"%d년"},ordinalParse:/\d{1,2}일/,ordinal:"%d일",meridiemParse:/오전|오후/,isPM:function(e){return"오후"===e},meridiem:function(e,t,n){return e<12?"오전":"오후"}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={0:"-чү",1:"-чи",2:"-чи",3:"-чү",4:"-чү",5:"-чи",6:"-чы",7:"-чи",8:"-чи",9:"-чу",10:"-чу",20:"-чы",30:"-чу",40:"-чы",50:"-чү",60:"-чы",70:"-чи",80:"-чи",90:"-чу",100:"-чү"},n=e.defineLocale("ky",{months:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),monthsShort:"янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек".split("_"),weekdays:"Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби".split("_"),weekdaysShort:"Жек_Дүй_Шей_Шар_Бей_Жум_Ише".split("_"),weekdaysMin:"Жк_Дй_Шй_Шр_Бй_Жм_Иш".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Бүгүн саат] LT",nextDay:"[Эртең саат] LT",nextWeek:"dddd [саат] LT",lastDay:"[Кече саат] LT",lastWeek:"[Өткен аптанын] dddd [күнү] [саат] LT",sameElse:"L"},relativeTime:{future:"%s ичинде",past:"%s мурун",s:"бирнече секунд",m:"бир мүнөт",mm:"%d мүнөт",h:"бир саат",hh:"%d саат",d:"бир күн",dd:"%d күн",M:"бир ай",MM:"%d ай",y:"бир жыл",yy:"%d жыл"},ordinalParse:/\d{1,2}-(чи|чы|чү|чу)/,ordinal:function(e){var n=e%10,r=e>=100?100:null;return e+(t[e]||t[n]||t[r])},week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return t?a[n][0]:a[n][1]}function n(e){var t=e.substr(0,e.indexOf(" "));return a(t)?"a "+e:"an "+e}function r(e){var t=e.substr(0,e.indexOf(" "));return a(t)?"viru "+e:"virun "+e}function a(e){if(e=parseInt(e,10),isNaN(e))return!1;if(e<0)return!0;if(e<10)return 4<=e&&e<=7;if(e<100){var t=e%10,n=e/10;return a(0===t?n:t)}if(e<1e4){for(;e>=10;)e/=10;return a(e)}return e/=1e3,a(e)}var i=e.defineLocale("lb",{months:"Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mé_Dë_Më_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[Gëschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:n,past:r,s:"e puer Sekonnen",m:t,mm:"%d Minutten",h:t,hh:"%d Stonnen",d:t,dd:"%d Deeg",M:t,MM:"%d Méint",y:t,yy:"%d Joer"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("lo",{months:"ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ".split("_"),monthsShort:"ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ".split("_"),weekdays:"ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ".split("_"),weekdaysShort:"ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ".split("_"),weekdaysMin:"ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"ວັນdddd D MMMM YYYY HH:mm"},meridiemParse:/ຕອນເຊົ້າ|ຕອນແລງ/,isPM:function(e){return"ຕອນແລງ"===e},meridiem:function(e,t,n){return e<12?"ຕອນເຊົ້າ":"ຕອນແລງ"},calendar:{sameDay:"[ມື້ນີ້ເວລາ] LT",nextDay:"[ມື້ອື່ນເວລາ] LT",nextWeek:"[ວັນ]dddd[ໜ້າເວລາ] LT",lastDay:"[ມື້ວານນີ້ເວລາ] LT",lastWeek:"[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT",sameElse:"L"},relativeTime:{future:"ອີກ %s",past:"%sຜ່ານມາ",s:"ບໍ່ເທົ່າໃດວິນາທີ",m:"1 ນາທີ",mm:"%d ນາທີ",h:"1 ຊົ່ວໂມງ",hh:"%d ຊົ່ວໂມງ",d:"1 ມື້",dd:"%d ມື້",M:"1 ເດືອນ",MM:"%d ເດືອນ",y:"1 ປີ",yy:"%d ປີ"},ordinalParse:/(ທີ່)\d{1,2}/,ordinal:function(e){return"ທີ່"+e}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){return t?"kelios sekundės":r?"kelių sekundžių":"kelias sekundes"}function n(e,t,n,r){return t?a(n)[0]:r?a(n)[1]:a(n)[2]}function r(e){return e%10===0||e>10&&e<20}function a(e){return o[e].split("_")}function i(e,t,i,o){var s=e+" ";return 1===e?s+n(e,t,i[0],o):t?s+(r(e)?a(i)[1]:a(i)[0]):o?s+a(i)[1]:s+(r(e)?a(i)[1]:a(i)[2])}var o={m:"minutė_minutės_minutę",mm:"minutės_minučių_minutes",h:"valanda_valandos_valandą",hh:"valandos_valandų_valandas",d:"diena_dienos_dieną",dd:"dienos_dienų_dienas",M:"mėnuo_mėnesio_mėnesį",MM:"mėnesiai_mėnesių_mėnesius",y:"metai_metų_metus",yy:"metai_metų_metus"},s=e.defineLocale("lt",{months:{format:"sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis".split("_"),isFormat:/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),weekdaysMin:"S_P_A_T_K_Pn_Š".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[Šiandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Praėjusį] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prieš %s",s:t,m:n,mm:i,h:n,hh:i,d:n,dd:i,M:n,MM:i,y:n,yy:i},ordinalParse:/\d{1,2}-oji/,ordinal:function(e){return e+"-oji"},week:{dow:1,doy:4}});return s})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n){return n?t%10===1&&t%100!==11?e[2]:e[3]:t%10===1&&t%100!==11?e[0]:e[1]}function n(e,n,r){return e+" "+t(i[r],e,n)}function r(e,n,r){return t(i[r],e,n)}function a(e,t){return t?"dažas sekundes":"dažām sekundēm"}var i={m:"minūtes_minūtēm_minūte_minūtes".split("_"),mm:"minūtes_minūtēm_minūte_minūtes".split("_"),h:"stundas_stundām_stunda_stundas".split("_"),hh:"stundas_stundām_stunda_stundas".split("_"),d:"dienas_dienām_diena_dienas".split("_"),dd:"dienas_dienām_diena_dienas".split("_"),M:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),MM:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")},o=e.defineLocale("lv",{months:"janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),weekdays:"svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[Šodien pulksten] LT",nextDay:"[Rīt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pagājušā] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"pēc %s",past:"pirms %s",s:a,m:r,mm:n,h:r,hh:n,d:r,dd:n,M:r,MM:n,y:r,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return o})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={words:{m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mjesec","mjeseca","mjeseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(e,t){return 1===e?t[0]:e>=2&&e<=4?t[1]:t[2]},translate:function(e,n,r){var a=t.words[r];return 1===r.length?n?a[0]:a[1]:e+" "+t.correctGrammaticalCase(e,a)}},n=e.defineLocale("me",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sjutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){var e=["[prošle] [nedjelje] [u] LT","[prošlog] [ponedjeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srijede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"];return e[this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"nekoliko sekundi",m:t.translate,mm:t.translate,h:t.translate,hh:t.translate,d:"dan",dd:t.translate,M:"mjesec",MM:t.translate,y:"godinu",yy:t.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("mi",{months:"Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea".split("_"),monthsShort:"Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki".split("_"),monthsRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,weekdays:"Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei".split("_"),weekdaysShort:"Ta_Ma_Tū_We_Tāi_Pa_Hā".split("_"),weekdaysMin:"Ta_Ma_Tū_We_Tāi_Pa_Hā".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [i] HH:mm",LLLL:"dddd, D MMMM YYYY [i] HH:mm"},calendar:{sameDay:"[i teie mahana, i] LT",nextDay:"[apopo i] LT",nextWeek:"dddd [i] LT",lastDay:"[inanahi i] LT",lastWeek:"dddd [whakamutunga i] LT",sameElse:"L"},relativeTime:{future:"i roto i %s",past:"%s i mua",s:"te hēkona ruarua",m:"he meneti",mm:"%d meneti",h:"te haora",hh:"%d haora",d:"he ra",dd:"%d ra",M:"he marama",MM:"%d marama",y:"he tau",yy:"%d tau"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("mk",{months:"јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),monthsShort:"јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),weekdays:"недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),weekdaysShort:"нед_пон_вто_сре_чет_пет_саб".split("_"),weekdaysMin:"нe_пo_вт_ср_че_пе_сa".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Денес во] LT",nextDay:"[Утре во] LT",nextWeek:"[Во] dddd [во] LT",lastDay:"[Вчера во] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[Изминатата] dddd [во] LT";case 1:case 2:case 4:case 5:return"[Изминатиот] dddd [во] LT"}},sameElse:"L"},relativeTime:{future:"после %s",past:"пред %s",s:"неколку секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дена",M:"месец",MM:"%d месеци",y:"година",yy:"%d години"},ordinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(e){var t=e%10,n=e%100;return 0===e?e+"-ев":0===n?e+"-ен":n>10&&n<20?e+"-ти":1===t?e+"-ви":2===t?e+"-ри":7===t||8===t?e+"-ми":e+"-ти"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ml",{months:"ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ".split("_"),monthsShort:"ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.".split("_"),monthsParseExact:!0,weekdays:"ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച".split("_"),weekdaysShort:"ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി".split("_"),weekdaysMin:"ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ".split("_"),longDateFormat:{LT:"A h:mm -നു",LTS:"A h:mm:ss -നു",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm -നു",LLLL:"dddd, D MMMM YYYY, A h:mm -നു"},calendar:{sameDay:"[ഇന്ന്] LT",nextDay:"[നാളെ] LT",nextWeek:"dddd, LT",lastDay:"[ഇന്നലെ] LT",lastWeek:"[കഴിഞ്ഞ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s കഴിഞ്ഞ്",past:"%s മുൻപ്",s:"അൽപ നിമിഷങ്ങൾ",m:"ഒരു മിനിറ്റ്",mm:"%d മിനിറ്റ്",h:"ഒരു മണിക്കൂർ",hh:"%d മണിക്കൂർ",d:"ഒരു ദിവസം",dd:"%d ദിവസം",M:"ഒരു മാസം",MM:"%d മാസം",y:"ഒരു വർഷം",yy:"%d വർഷം"},meridiemParse:/രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,meridiemHour:function(e,t){return 12===e&&(e=0),"രാത്രി"===t&&e>=4||"ഉച്ച കഴിഞ്ഞ്"===t||"വൈകുന്നേരം"===t?e+12:e},meridiem:function(e,t,n){return e<4?"രാത്രി":e<12?"രാവിലെ":e<17?"ഉച്ച കഴിഞ്ഞ്":e<20?"വൈകുന്നേരം":"രാത്രി"}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a="";if(t)switch(n){case"s":a="काही सेकंद";break;case"m":a="एक मिनिट";break;case"mm":a="%d मिनिटे";break;case"h":a="एक तास";break;case"hh":a="%d तास";break;case"d":a="एक दिवस";break;case"dd":a="%d दिवस";break;case"M":a="एक महिना";break;case"MM":a="%d महिने";break;case"y":a="एक वर्ष";break;case"yy":a="%d वर्षे"}else switch(n){case"s":a="काही सेकंदां";break;case"m":a="एका मिनिटा";break;case"mm":a="%d मिनिटां";break;case"h":a="एका तासा";break;case"hh":a="%d तासां";break;case"d":a="एका दिवसा";break;case"dd":a="%d दिवसां";break;case"M":a="एका महिन्या";break;case"MM":a="%d महिन्यां";break;case"y":a="एका वर्षा";break;case"yy":a="%d वर्षां"}return a.replace(/%d/i,e)}var n={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},r={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},a=e.defineLocale("mr",{months:"जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर".split("_"),monthsShort:"जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.".split("_"),monthsParseExact:!0,weekdays:"रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm वाजता",LTS:"A h:mm:ss वाजता",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm वाजता",LLLL:"dddd, D MMMM YYYY, A h:mm वाजता"},calendar:{sameDay:"[आज] LT",nextDay:"[उद्या] LT",nextWeek:"dddd, LT",lastDay:"[काल] LT",lastWeek:"[मागील] dddd, LT",sameElse:"L"},relativeTime:{future:"%sमध्ये",past:"%sपूर्वी",s:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return r[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return n[e]})},meridiemParse:/रात्री|सकाळी|दुपारी|सायंकाळी/,meridiemHour:function(e,t){return 12===e&&(e=0),"रात्री"===t?e<4?e:e+12:"सकाळी"===t?e:"दुपारी"===t?e>=10?e:e+12:"सायंकाळी"===t?e+12:void 0},meridiem:function(e,t,n){return e<4?"रात्री":e<10?"सकाळी":e<17?"दुपारी":e<20?"सायंकाळी":"रात्री"},week:{dow:0,doy:6}});return a})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,t){return 12===e&&(e=0),"pagi"===t?e:"tengahari"===t?e>=11?e:e+12:"petang"===t||"malam"===t?e+12:void 0},meridiem:function(e,t,n){return e<11?"pagi":e<15?"tengahari":e<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ms",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,t){return 12===e&&(e=0),"pagi"===t?e:"tengahari"===t?e>=11?e:e+12:"petang"===t||"malam"===t?e+12:void 0},meridiem:function(e,t,n){return e<11?"pagi":e<15?"tengahari":e<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"၁",2:"၂",3:"၃",4:"၄",5:"၅",6:"၆",7:"၇",8:"၈",9:"၉",0:"၀"},n={"၁":"1","၂":"2","၃":"3","၄":"4","၅":"5","၆":"6","၇":"7","၈":"8","၉":"9","၀":"0"},r=e.defineLocale("my",{months:"ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ".split("_"),monthsShort:"ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ".split("_"),weekdays:"တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ".split("_"),weekdaysShort:"နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),weekdaysMin:"နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),longDateFormat:{LT:"HH:mm", +LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[ယနေ.] LT [မှာ]",nextDay:"[မနက်ဖြန်] LT [မှာ]",nextWeek:"dddd LT [မှာ]",lastDay:"[မနေ.က] LT [မှာ]",lastWeek:"[ပြီးခဲ့သော] dddd LT [မှာ]",sameElse:"L"},relativeTime:{future:"လာမည့် %s မှာ",past:"လွန်ခဲ့သော %s က",s:"စက္ကန်.အနည်းငယ်",m:"တစ်မိနစ်",mm:"%d မိနစ်",h:"တစ်နာရီ",hh:"%d နာရီ",d:"တစ်ရက်",dd:"%d ရက်",M:"တစ်လ",MM:"%d လ",y:"တစ်နှစ်",yy:"%d နှစ်"},preparse:function(e){return e.replace(/[၁၂၃၄၅၆၇၈၉၀]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},week:{dow:1,doy:4}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"sø._ma._ti._on._to._fr._lø.".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en måned",MM:"%d måneder",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},n={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},r=e.defineLocale("ne",{months:"जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर".split("_"),monthsShort:"जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.".split("_"),monthsParseExact:!0,weekdays:"आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार".split("_"),weekdaysShort:"आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.".split("_"),weekdaysMin:"आ._सो._मं._बु._बि._शु._श.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"Aको h:mm बजे",LTS:"Aको h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, Aको h:mm बजे",LLLL:"dddd, D MMMM YYYY, Aको h:mm बजे"},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/राति|बिहान|दिउँसो|साँझ/,meridiemHour:function(e,t){return 12===e&&(e=0),"राति"===t?e<4?e:e+12:"बिहान"===t?e:"दिउँसो"===t?e>=10?e:e+12:"साँझ"===t?e+12:void 0},meridiem:function(e,t,n){return e<3?"राति":e<12?"बिहान":e<16?"दिउँसो":e<20?"साँझ":"राति"},calendar:{sameDay:"[आज] LT",nextDay:"[भोलि] LT",nextWeek:"[आउँदो] dddd[,] LT",lastDay:"[हिजो] LT",lastWeek:"[गएको] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%sमा",past:"%s अगाडि",s:"केही क्षण",m:"एक मिनेट",mm:"%d मिनेट",h:"एक घण्टा",hh:"%d घण्टा",d:"एक दिन",dd:"%d दिन",M:"एक महिना",MM:"%d महिना",y:"एक बर्ष",yy:"%d बर्ष"},week:{dow:0,doy:6}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),n="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),r=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],a=/^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,i=e.defineLocale("nl-be",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,r){return/-MMM-/.test(r)?n[e.month()]:t[e.month()]},monthsRegex:a,monthsShortRegex:a,monthsStrictRegex:/^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:r,longMonthsParse:r,shortMonthsParse:r,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),n="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),r=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],a=/^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,i=e.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,r){return/-MMM-/.test(r)?n[e.month()]:t[e.month()]},monthsRegex:a,monthsShortRegex:a,monthsStrictRegex:/^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:r,longMonthsParse:r,shortMonthsParse:r,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"sun_mån_tys_ons_tor_fre_lau".split("_"),weekdaysMin:"su_må_ty_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I går klokka] LT",lastWeek:"[Føregåande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s sidan",s:"nokre sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",M:"ein månad",MM:"%d månader",y:"eit år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"੧",2:"੨",3:"੩",4:"੪",5:"੫",6:"੬",7:"੭",8:"੮",9:"੯",0:"੦"},n={"੧":"1","੨":"2","੩":"3","੪":"4","੫":"5","੬":"6","੭":"7","੮":"8","੯":"9","੦":"0"},r=e.defineLocale("pa-in",{months:"ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ".split("_"),monthsShort:"ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ".split("_"),weekdays:"ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ".split("_"),weekdaysShort:"ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ".split("_"),weekdaysMin:"ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ".split("_"),longDateFormat:{LT:"A h:mm ਵਜੇ",LTS:"A h:mm:ss ਵਜੇ",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm ਵਜੇ",LLLL:"dddd, D MMMM YYYY, A h:mm ਵਜੇ"},calendar:{sameDay:"[ਅਜ] LT",nextDay:"[ਕਲ] LT",nextWeek:"dddd, LT",lastDay:"[ਕਲ] LT",lastWeek:"[ਪਿਛਲੇ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ਵਿੱਚ",past:"%s ਪਿਛਲੇ",s:"ਕੁਝ ਸਕਿੰਟ",m:"ਇਕ ਮਿੰਟ",mm:"%d ਮਿੰਟ",h:"ਇੱਕ ਘੰਟਾ",hh:"%d ਘੰਟੇ",d:"ਇੱਕ ਦਿਨ",dd:"%d ਦਿਨ",M:"ਇੱਕ ਮਹੀਨਾ",MM:"%d ਮਹੀਨੇ",y:"ਇੱਕ ਸਾਲ",yy:"%d ਸਾਲ"},preparse:function(e){return e.replace(/[੧੨੩੪੫੬੭੮੯੦]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,meridiemHour:function(e,t){return 12===e&&(e=0),"ਰਾਤ"===t?e<4?e:e+12:"ਸਵੇਰ"===t?e:"ਦੁਪਹਿਰ"===t?e>=10?e:e+12:"ਸ਼ਾਮ"===t?e+12:void 0},meridiem:function(e,t,n){return e<4?"ਰਾਤ":e<10?"ਸਵੇਰ":e<17?"ਦੁਪਹਿਰ":e<20?"ਸ਼ਾਮ":"ਰਾਤ"},week:{dow:0,doy:6}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e){return e%10<5&&e%10>1&&~~(e/10)%10!==1}function n(e,n,r){var a=e+" ";switch(r){case"m":return n?"minuta":"minutę";case"mm":return a+(t(e)?"minuty":"minut");case"h":return n?"godzina":"godzinę";case"hh":return a+(t(e)?"godziny":"godzin");case"MM":return a+(t(e)?"miesiące":"miesięcy");case"yy":return a+(t(e)?"lata":"lat")}}var r="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),a="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_"),i=e.defineLocale("pl",{months:function(e,t){return""===t?"("+a[e.month()]+"|"+r[e.month()]+")":/D MMMM/.test(t)?a[e.month()]:r[e.month()]},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_śr_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:n,mm:n,h:n,hh:n,d:"1 dzień",dd:"%d dni",M:"miesiąc",MM:n,y:"rok",yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("pt-br",{months:"Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [às] HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atrás",s:"poucos segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº"});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("pt",{months:"Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n){var r={mm:"minute",hh:"ore",dd:"zile",MM:"luni",yy:"ani"},a=" ";return(e%100>=20||e>=100&&e%100===0)&&(a=" de "),e+a+r[n]}var n=e.defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[mâine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s în urmă",s:"câteva secunde",m:"un minut",mm:t,h:"o oră",hh:t,d:"o zi",dd:t,M:"o lună",MM:t,y:"un an",yy:t},week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t){var n=e.split("_");return t%10===1&&t%100!==11?n[0]:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?n[1]:n[2]}function n(e,n,r){var a={mm:n?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",MM:"месяц_месяца_месяцев",yy:"год_года_лет"};return"m"===r?n?"минута":"минуту":e+" "+t(a[r],+e)}var r=[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[йя]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i],a=e.defineLocale("ru",{months:{format:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_"),standalone:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_")},monthsShort:{format:"янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.".split("_"),standalone:"янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.".split("_")},weekdays:{standalone:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),format:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_"),isFormat:/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/},weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:r,longMonthsParse:r,shortMonthsParse:r,monthsRegex:/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,monthsShortRegex:/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,monthsStrictRegex:/^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,monthsShortStrictRegex:/^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., HH:mm",LLLL:"dddd, D MMMM YYYY г., HH:mm"},calendar:{sameDay:"[Сегодня в] LT",nextDay:"[Завтра в] LT",lastDay:"[Вчера в] LT",nextWeek:function(e){if(e.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В следующее] dddd [в] LT";case 1:case 2:case 4:return"[В следующий] dddd [в] LT";case 3:case 5:case 6:return"[В следующую] dddd [в] LT"}},lastWeek:function(e){if(e.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В прошлое] dddd [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",m:n,mm:n,h:"час",hh:n,d:"день",dd:n,M:"месяц",MM:n,y:"год",yy:n},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(e){return/^(дня|вечера)$/.test(e)},meridiem:function(e,t,n){return e<4?"ночи":e<12?"утра":e<17?"дня":"вечера"},ordinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":return e+"-й";case"D":return e+"-го";case"w":case"W":return e+"-я";default:return e}},week:{dow:1,doy:7}});return a})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("se",{months:"ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu".split("_"),monthsShort:"ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov".split("_"),weekdays:"sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat".split("_"),weekdaysShort:"sotn_vuos_maŋ_gask_duor_bear_láv".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s geažes",past:"maŋit %s",s:"moadde sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta mánnu",MM:"%d mánut",y:"okta jahki",yy:"%d jagit"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("si",{months:"ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්".split("_"),monthsShort:"ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ".split("_"),weekdays:"ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා".split("_"),weekdaysShort:"ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන".split("_"),weekdaysMin:"ඉ_ස_අ_බ_බ්‍ර_සි_සෙ".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"a h:mm",LTS:"a h:mm:ss",L:"YYYY/MM/DD",LL:"YYYY MMMM D",LLL:"YYYY MMMM D, a h:mm",LLLL:"YYYY MMMM D [වැනි] dddd, a h:mm:ss"},calendar:{sameDay:"[අද] LT[ට]",nextDay:"[හෙට] LT[ට]",nextWeek:"dddd LT[ට]",lastDay:"[ඊයේ] LT[ට]",lastWeek:"[පසුගිය] dddd LT[ට]",sameElse:"L"},relativeTime:{future:"%sකින්",past:"%sකට පෙර",s:"තත්පර කිහිපය",m:"මිනිත්තුව",mm:"මිනිත්තු %d",h:"පැය",hh:"පැය %d",d:"දිනය",dd:"දින %d",M:"මාසය",MM:"මාස %d",y:"වසර",yy:"වසර %d"},ordinalParse:/\d{1,2} වැනි/,ordinal:function(e){return e+" වැනි"},meridiemParse:/පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,isPM:function(e){return"ප.ව."===e||"පස් වරු"===e},meridiem:function(e,t,n){return e>11?n?"ප.ව.":"පස් වරු":n?"පෙ.ව.":"පෙර වරු"}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e){return e>1&&e<5}function n(e,n,r,a){var i=e+" ";switch(r){case"s":return n||a?"pár sekúnd":"pár sekundami";case"m":return n?"minúta":a?"minútu":"minútou";case"mm":return n||a?i+(t(e)?"minúty":"minút"):i+"minútami";case"h":return n?"hodina":a?"hodinu":"hodinou";case"hh":return n||a?i+(t(e)?"hodiny":"hodín"):i+"hodinami";case"d":return n||a?"deň":"dňom";case"dd":return n||a?i+(t(e)?"dni":"dní"):i+"dňami";case"M":return n||a?"mesiac":"mesiacom";case"MM":return n||a?i+(t(e)?"mesiace":"mesiacov"):i+"mesiacmi";case"y":return n||a?"rok":"rokom";case"yy":return n||a?i+(t(e)?"roky":"rokov"):i+"rokmi"}}var r="január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),a="jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_"),i=e.defineLocale("sk",{months:r,monthsShort:a,weekdays:"nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_št_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_št_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nedeľu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo štvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[včera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulú nedeľu o] LT";case 1:case 2:return"[minulý] dddd [o] LT";case 3:return"[minulú stredu o] LT";case 4:case 5:return"[minulý] dddd [o] LT";case 6:return"[minulú sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a=e+" ";switch(n){case"s":return t||r?"nekaj sekund":"nekaj sekundami";case"m":return t?"ena minuta":"eno minuto";case"mm":return a+=1===e?t?"minuta":"minuto":2===e?t||r?"minuti":"minutama":e<5?t||r?"minute":"minutami":t||r?"minut":"minutami";case"h":return t?"ena ura":"eno uro";case"hh":return a+=1===e?t?"ura":"uro":2===e?t||r?"uri":"urama":e<5?t||r?"ure":"urami":t||r?"ur":"urami";case"d":return t||r?"en dan":"enim dnem";case"dd":return a+=1===e?t||r?"dan":"dnem":2===e?t||r?"dni":"dnevoma":t||r?"dni":"dnevi";case"M":return t||r?"en mesec":"enim mesecem";case"MM":return a+=1===e?t||r?"mesec":"mesecem":2===e?t||r?"meseca":"mesecema":e<5?t||r?"mesece":"meseci":t||r?"mesecev":"meseci";case"y":return t||r?"eno leto":"enim letom";case"yy":return a+=1===e?t||r?"leto":"letom":2===e?t||r?"leti":"letoma":e<5?t||r?"leta":"leti":t||r?"let":"leti"}}var n=e.defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._čet._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_če_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[včeraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prejšnjo] [nedeljo] [ob] LT";case 3:return"[prejšnjo] [sredo] [ob] LT";case 6:return"[prejšnjo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prejšnji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"čez %s",past:"pred %s",s:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("sq",{months:"Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"),monthsShort:"Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"),weekdays:"E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"),weekdaysShort:"Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"),weekdaysMin:"D_H_Ma_Më_E_P_Sh".split("_"),weekdaysParseExact:!0,meridiemParse:/PD|MD/,isPM:function(e){return"M"===e.charAt(0)},meridiem:function(e,t,n){return e<12?"PD":"MD"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Sot në] LT",nextDay:"[Nesër në] LT",nextWeek:"dddd [në] LT",lastDay:"[Dje në] LT",lastWeek:"dddd [e kaluar në] LT",sameElse:"L"},relativeTime:{future:"në %s",past:"%s më parë",s:"disa sekonda",m:"një minutë",mm:"%d minuta",h:"një orë",hh:"%d orë",d:"një ditë",dd:"%d ditë",M:"një muaj",MM:"%d muaj",y:"një vit",yy:"%d vite"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={words:{m:["један минут","једне минуте"],mm:["минут","минуте","минута"],h:["један сат","једног сата"],hh:["сат","сата","сати"],dd:["дан","дана","дана"],MM:["месец","месеца","месеци"],yy:["година","године","година"]},correctGrammaticalCase:function(e,t){return 1===e?t[0]:e>=2&&e<=4?t[1]:t[2]},translate:function(e,n,r){var a=t.words[r];return 1===r.length?n?a[0]:a[1]:e+" "+t.correctGrammaticalCase(e,a)}},n=e.defineLocale("sr-cyrl",{months:"јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар".split("_"),monthsShort:"јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.".split("_"),monthsParseExact:!0,weekdays:"недеља_понедељак_уторак_среда_четвртак_петак_субота".split("_"),weekdaysShort:"нед._пон._уто._сре._чет._пет._суб.".split("_"),weekdaysMin:"не_по_ут_ср_че_пе_су".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[данас у] LT",nextDay:"[сутра у] LT",nextWeek:function(){switch(this.day()){case 0:return"[у] [недељу] [у] LT";case 3:return"[у] [среду] [у] LT";case 6:return"[у] [суботу] [у] LT";case 1:case 2:case 4:case 5:return"[у] dddd [у] LT"}},lastDay:"[јуче у] LT",lastWeek:function(){var e=["[прошле] [недеље] [у] LT","[прошлог] [понедељка] [у] LT","[прошлог] [уторка] [у] LT","[прошле] [среде] [у] LT","[прошлог] [четвртка] [у] LT","[прошлог] [петка] [у] LT","[прошле] [суботе] [у] LT"];return e[this.day()]},sameElse:"L"},relativeTime:{future:"за %s",past:"пре %s",s:"неколико секунди",m:t.translate,mm:t.translate,h:t.translate,hh:t.translate,d:"дан",dd:t.translate,M:"месец",MM:t.translate,y:"годину",yy:t.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={words:{m:["jedan minut","jedne minute"],mm:["minut","minute","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mesec","meseca","meseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(e,t){return 1===e?t[0]:e>=2&&e<=4?t[1]:t[2]},translate:function(e,n,r){var a=t.words[r];return 1===r.length?n?a[0]:a[1]:e+" "+t.correctGrammaticalCase(e,a)}},n=e.defineLocale("sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){var e=["[prošle] [nedelje] [u] LT","[prošlog] [ponedeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"];return e[this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",m:t.translate,mm:t.translate,h:t.translate,hh:t.translate,d:"dan",dd:t.translate,M:"mesec",MM:t.translate,y:"godinu",yy:t.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("ss",{months:"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split("_"),monthsShort:"Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo".split("_"),weekdays:"Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo".split("_"),weekdaysShort:"Lis_Umb_Lsb_Les_Lsi_Lsh_Umg".split("_"),weekdaysMin:"Li_Us_Lb_Lt_Ls_Lh_Ug".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Namuhla nga] LT",nextDay:"[Kusasa nga] LT",nextWeek:"dddd [nga] LT",lastDay:"[Itolo nga] LT",lastWeek:"dddd [leliphelile] [nga] LT",sameElse:"L"},relativeTime:{future:"nga %s",past:"wenteka nga %s",s:"emizuzwana lomcane",m:"umzuzu",mm:"%d emizuzu",h:"lihora",hh:"%d emahora",d:"lilanga",dd:"%d emalanga",M:"inyanga",MM:"%d tinyanga",y:"umnyaka",yy:"%d iminyaka"},meridiemParse:/ekuseni|emini|entsambama|ebusuku/,meridiem:function(e,t,n){return e<11?"ekuseni":e<15?"emini":e<19?"entsambama":"ebusuku"},meridiemHour:function(e,t){return 12===e&&(e=0),"ekuseni"===t?e:"emini"===t?e>=11?e:e+12:"entsambama"===t||"ebusuku"===t?0===e?0:e+12:void 0},ordinalParse:/\d{1,2}/,ordinal:"%d",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"[På] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}(e|a)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"e":1===t?"a":2===t?"a":"e";return e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("sw",{months:"Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba".split("_"), +monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des".split("_"),weekdays:"Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi".split("_"),weekdaysShort:"Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos".split("_"),weekdaysMin:"J2_J3_J4_J5_Al_Ij_J1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[leo saa] LT",nextDay:"[kesho saa] LT",nextWeek:"[wiki ijayo] dddd [saat] LT",lastDay:"[jana] LT",lastWeek:"[wiki iliyopita] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s baadaye",past:"tokea %s",s:"hivi punde",m:"dakika moja",mm:"dakika %d",h:"saa limoja",hh:"masaa %d",d:"siku moja",dd:"masiku %d",M:"mwezi mmoja",MM:"miezi %d",y:"mwaka mmoja",yy:"miaka %d"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"௧",2:"௨",3:"௩",4:"௪",5:"௫",6:"௬",7:"௭",8:"௮",9:"௯",0:"௦"},n={"௧":"1","௨":"2","௩":"3","௪":"4","௫":"5","௬":"6","௭":"7","௮":"8","௯":"9","௦":"0"},r=e.defineLocale("ta",{months:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),monthsShort:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),weekdays:"ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை".split("_"),weekdaysShort:"ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி".split("_"),weekdaysMin:"ஞா_தி_செ_பு_வி_வெ_ச".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, HH:mm",LLLL:"dddd, D MMMM YYYY, HH:mm"},calendar:{sameDay:"[இன்று] LT",nextDay:"[நாளை] LT",nextWeek:"dddd, LT",lastDay:"[நேற்று] LT",lastWeek:"[கடந்த வாரம்] dddd, LT",sameElse:"L"},relativeTime:{future:"%s இல்",past:"%s முன்",s:"ஒரு சில விநாடிகள்",m:"ஒரு நிமிடம்",mm:"%d நிமிடங்கள்",h:"ஒரு மணி நேரம்",hh:"%d மணி நேரம்",d:"ஒரு நாள்",dd:"%d நாட்கள்",M:"ஒரு மாதம்",MM:"%d மாதங்கள்",y:"ஒரு வருடம்",yy:"%d ஆண்டுகள்"},ordinalParse:/\d{1,2}வது/,ordinal:function(e){return e+"வது"},preparse:function(e){return e.replace(/[௧௨௩௪௫௬௭௮௯௦]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,meridiem:function(e,t,n){return e<2?" யாமம்":e<6?" வைகறை":e<10?" காலை":e<14?" நண்பகல்":e<18?" எற்பாடு":e<22?" மாலை":" யாமம்"},meridiemHour:function(e,t){return 12===e&&(e=0),"யாமம்"===t?e<2?e:e+12:"வைகறை"===t||"காலை"===t?e:"நண்பகல்"===t&&e>=10?e:e+12},week:{dow:0,doy:6}});return r})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("te",{months:"జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్".split("_"),monthsShort:"జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.".split("_"),monthsParseExact:!0,weekdays:"ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం".split("_"),weekdaysShort:"ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని".split("_"),weekdaysMin:"ఆ_సో_మం_బు_గు_శు_శ".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[నేడు] LT",nextDay:"[రేపు] LT",nextWeek:"dddd, LT",lastDay:"[నిన్న] LT",lastWeek:"[గత] dddd, LT",sameElse:"L"},relativeTime:{future:"%s లో",past:"%s క్రితం",s:"కొన్ని క్షణాలు",m:"ఒక నిమిషం",mm:"%d నిమిషాలు",h:"ఒక గంట",hh:"%d గంటలు",d:"ఒక రోజు",dd:"%d రోజులు",M:"ఒక నెల",MM:"%d నెలలు",y:"ఒక సంవత్సరం",yy:"%d సంవత్సరాలు"},ordinalParse:/\d{1,2}వ/,ordinal:"%dవ",meridiemParse:/రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,meridiemHour:function(e,t){return 12===e&&(e=0),"రాత్రి"===t?e<4?e:e+12:"ఉదయం"===t?e:"మధ్యాహ్నం"===t?e>=10?e:e+12:"సాయంత్రం"===t?e+12:void 0},meridiem:function(e,t,n){return e<4?"రాత్రి":e<10?"ఉదయం":e<17?"మధ్యాహ్నం":e<20?"సాయంత్రం":"రాత్రి"},week:{dow:0,doy:6}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("tet",{months:"Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez".split("_"),weekdays:"Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu".split("_"),weekdaysShort:"Dom_Seg_Ters_Kua_Kint_Sext_Sab".split("_"),weekdaysMin:"Do_Seg_Te_Ku_Ki_Sex_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Ohin iha] LT",nextDay:"[Aban iha] LT",nextWeek:"dddd [iha] LT",lastDay:"[Horiseik iha] LT",lastWeek:"dddd [semana kotuk] [iha] LT",sameElse:"L"},relativeTime:{future:"iha %s",past:"%s liuba",s:"minutu balun",m:"minutu ida",mm:"minutus %d",h:"horas ida",hh:"horas %d",d:"loron ida",dd:"loron %d",M:"fulan ida",MM:"fulan %d",y:"tinan ida",yy:"tinan %d"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.".split("_"),monthsParseExact:!0,weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY/MM/DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา H:mm",LLLL:"วันddddที่ D MMMM YYYY เวลา H:mm"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(e){return"หลังเที่ยง"===e},meridiem:function(e,t,n){return e<12?"ก่อนเที่ยง":"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},ordinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e){var t=e;return t=e.indexOf("jaj")!==-1?t.slice(0,-3)+"leS":e.indexOf("jar")!==-1?t.slice(0,-3)+"waQ":e.indexOf("DIS")!==-1?t.slice(0,-3)+"nem":t+" pIq"}function n(e){var t=e;return t=e.indexOf("jaj")!==-1?t.slice(0,-3)+"Hu’":e.indexOf("jar")!==-1?t.slice(0,-3)+"wen":e.indexOf("DIS")!==-1?t.slice(0,-3)+"ben":t+" ret"}function r(e,t,n,r){var i=a(e);switch(n){case"mm":return i+" tup";case"hh":return i+" rep";case"dd":return i+" jaj";case"MM":return i+" jar";case"yy":return i+" DIS"}}function a(e){var t=Math.floor(e%1e3/100),n=Math.floor(e%100/10),r=e%10,a="";return t>0&&(a+=i[t]+"vatlh"),n>0&&(a+=(""!==a?" ":"")+i[n]+"maH"),r>0&&(a+=(""!==a?" ":"")+i[r]),""===a?"pagh":a}var i="pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut".split("_"),o=e.defineLocale("tlh",{months:"tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’".split("_"),monthsShort:"jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’".split("_"),monthsParseExact:!0,weekdays:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysShort:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysMin:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[DaHjaj] LT",nextDay:"[wa’leS] LT",nextWeek:"LLL",lastDay:"[wa’Hu’] LT",lastWeek:"LLL",sameElse:"L"},relativeTime:{future:t,past:n,s:"puS lup",m:"wa’ tup",mm:r,h:"wa’ rep",hh:r,d:"wa’ jaj",dd:r,M:"wa’ jar",MM:r,y:"wa’ DIS",yy:r},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return o})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'üncü",4:"'üncü",100:"'üncü",6:"'ncı",9:"'uncu",10:"'uncu",30:"'uncu",60:"'ıncı",90:"'ıncı"},n=e.defineLocale("tr",{months:"Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),monthsShort:"Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[yarın saat] LT",nextWeek:"[haftaya] dddd [saat] LT",lastDay:"[dün] LT",lastWeek:"[geçen hafta] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s önce",s:"birkaç saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir yıl",yy:"%d yıl"},ordinalParse:/\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,ordinal:function(e){if(0===e)return e+"'ıncı";var n=e%10,r=e%100-n,a=e>=100?100:null;return e+(t[n]||t[r]||t[a])},week:{dow:1,doy:7}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t,n,r){var a={s:["viensas secunds","'iensas secunds"],m:["'n míut","'iens míut"],mm:[e+" míuts",""+e+" míuts"],h:["'n þora","'iensa þora"],hh:[e+" þoras",""+e+" þoras"],d:["'n ziua","'iensa ziua"],dd:[e+" ziuas",""+e+" ziuas"],M:["'n mes","'iens mes"],MM:[e+" mesen",""+e+" mesen"],y:["'n ar","'iens ar"],yy:[e+" ars",""+e+" ars"]};return r?a[n][0]:t?a[n][0]:a[n][1]}var n=e.defineLocale("tzl",{months:"Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar".split("_"),monthsShort:"Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec".split("_"),weekdays:"Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi".split("_"),weekdaysShort:"Súl_Lún_Mai_Már_Xhú_Vié_Sát".split("_"),weekdaysMin:"Sú_Lú_Ma_Má_Xh_Vi_Sá".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"D. MMMM [dallas] YYYY",LLL:"D. MMMM [dallas] YYYY HH.mm",LLLL:"dddd, [li] D. MMMM [dallas] YYYY HH.mm"},meridiemParse:/d\'o|d\'a/i,isPM:function(e){return"d'o"===e.toLowerCase()},meridiem:function(e,t,n){return e>11?n?"d'o":"D'O":n?"d'a":"D'A"},calendar:{sameDay:"[oxhi à] LT",nextDay:"[demà à] LT",nextWeek:"dddd [à] LT",lastDay:"[ieiri à] LT",lastWeek:"[sür el] dddd [lasteu à] LT",sameElse:"L"},relativeTime:{future:"osprei %s",past:"ja%s",s:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return n})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("tzm-latn",{months:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),monthsShort:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),weekdays:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysShort:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysMin:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[asdkh g] LT",nextDay:"[aska g] LT",nextWeek:"dddd [g] LT",lastDay:"[assant g] LT",lastWeek:"dddd [g] LT",sameElse:"L"},relativeTime:{future:"dadkh s yan %s",past:"yan %s",s:"imik",m:"minuḍ",mm:"%d minuḍ",h:"saɛa",hh:"%d tassaɛin",d:"ass",dd:"%d ossan",M:"ayowr",MM:"%d iyyirn",y:"asgas",yy:"%d isgasn"},week:{dow:6,doy:12}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("tzm",{months:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),monthsShort:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),weekdays:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysShort:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysMin:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[ⴰⵙⴷⵅ ⴴ] LT",nextDay:"[ⴰⵙⴽⴰ ⴴ] LT",nextWeek:"dddd [ⴴ] LT",lastDay:"[ⴰⵚⴰⵏⵜ ⴴ] LT",lastWeek:"dddd [ⴴ] LT",sameElse:"L"},relativeTime:{future:"ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s",past:"ⵢⴰⵏ %s",s:"ⵉⵎⵉⴽ",m:"ⵎⵉⵏⵓⴺ",mm:"%d ⵎⵉⵏⵓⴺ",h:"ⵙⴰⵄⴰ",hh:"%d ⵜⴰⵙⵙⴰⵄⵉⵏ",d:"ⴰⵙⵙ",dd:"%d oⵙⵙⴰⵏ",M:"ⴰⵢoⵓⵔ",MM:"%d ⵉⵢⵢⵉⵔⵏ",y:"ⴰⵙⴳⴰⵙ",yy:"%d ⵉⵙⴳⴰⵙⵏ"},week:{dow:6,doy:12}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";function t(e,t){var n=e.split("_");return t%10===1&&t%100!==11?n[0]:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?n[1]:n[2]}function n(e,n,r){var a={mm:n?"хвилина_хвилини_хвилин":"хвилину_хвилини_хвилин",hh:n?"година_години_годин":"годину_години_годин",dd:"день_дні_днів",MM:"місяць_місяці_місяців",yy:"рік_роки_років"};return"m"===r?n?"хвилина":"хвилину":"h"===r?n?"година":"годину":e+" "+t(a[r],+e)}function r(e,t){var n={nominative:"неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота".split("_"),accusative:"неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу".split("_"),genitive:"неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи".split("_")},r=/(\[[ВвУу]\]) ?dddd/.test(t)?"accusative":/\[?(?:минулої|наступної)? ?\] ?dddd/.test(t)?"genitive":"nominative";return n[r][e.day()]}function a(e){return function(){return e+"о"+(11===this.hours()?"б":"")+"] LT"}}var i=e.defineLocale("uk",{months:{format:"січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня".split("_"),standalone:"січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень".split("_")},monthsShort:"січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),weekdays:r,weekdaysShort:"нд_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY р.",LLL:"D MMMM YYYY р., HH:mm",LLLL:"dddd, D MMMM YYYY р., HH:mm"},calendar:{sameDay:a("[Сьогодні "),nextDay:a("[Завтра "),lastDay:a("[Вчора "),nextWeek:a("[У] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return a("[Минулої] dddd [").call(this);case 1:case 2:case 4:return a("[Минулого] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"за %s",past:"%s тому",s:"декілька секунд",m:n,mm:n,h:"годину",hh:n,d:"день",dd:n,M:"місяць",MM:n,y:"рік",yy:n},meridiemParse:/ночі|ранку|дня|вечора/,isPM:function(e){return/^(дня|вечора)$/.test(e)},meridiem:function(e,t,n){return e<4?"ночі":e<12?"ранку":e<17?"дня":"вечора"},ordinalParse:/\d{1,2}-(й|го)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":case"w":case"W":return e+"-й";case"D":return e+"-го";default:return e}},week:{dow:1,doy:7}});return i})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("uz",{months:"январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр".split("_"),monthsShort:"янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),weekdays:"Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"),weekdaysShort:"Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"),weekdaysMin:"Як_Ду_Се_Чо_Па_Жу_Ша".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Бугун соат] LT [да]",nextDay:"[Эртага] LT [да]",nextWeek:"dddd [куни соат] LT [да]",lastDay:"[Кеча соат] LT [да]",lastWeek:"[Утган] dddd [куни соат] LT [да]",sameElse:"L"},relativeTime:{future:"Якин %s ичида",past:"Бир неча %s олдин",s:"фурсат",m:"бир дакика",mm:"%d дакика",h:"бир соат",hh:"%d соат",d:"бир кун",dd:"%d кун",M:"бир ой",MM:"%d ой",y:"бир йил",yy:"%d йил"},week:{dow:1,doy:7}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("vi",{months:"tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),monthsShort:"Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),monthsParseExact:!0,weekdays:"chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:!0,meridiemParse:/sa|ch/i,isPM:function(e){return/^ch$/i.test(e)},meridiem:function(e,t,n){return e<12?n?"sa":"SA":n?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [năm] YYYY",LLL:"D MMMM [năm] YYYY HH:mm",LLLL:"dddd, D MMMM [năm] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[Hôm nay lúc] LT",nextDay:"[Ngày mai lúc] LT",nextWeek:"dddd [tuần tới lúc] LT",lastDay:"[Hôm qua lúc] LT",lastWeek:"dddd [tuần rồi lúc] LT",sameElse:"L"},relativeTime:{future:"%s tới",past:"%s trước",s:"vài giây",m:"một phút",mm:"%d phút",h:"một giờ",hh:"%d giờ",d:"một ngày",dd:"%d ngày",M:"một tháng",MM:"%d tháng",y:"một năm",yy:"%d năm"},ordinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("x-pseudo",{months:"J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér".split("_"),monthsShort:"J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc".split("_"),monthsParseExact:!0,weekdays:"S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý".split("_"),weekdaysShort:"S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát".split("_"),weekdaysMin:"S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[T~ódá~ý át] LT",nextDay:"[T~ómó~rró~w át] LT",nextWeek:"dddd [át] LT",lastDay:"[Ý~ést~érdá~ý át] LT",lastWeek:"[L~ást] dddd [át] LT",sameElse:"L"},relativeTime:{future:"í~ñ %s",past:"%s á~gó",s:"á ~féw ~sécó~ñds",m:"á ~míñ~úté",mm:"%d m~íñú~tés",h:"á~ñ hó~úr",hh:"%d h~óúrs",d:"á ~dáý",dd:"%d d~áýs",M:"á ~móñ~th",MM:"%d m~óñt~hs",y:"á ~ýéár",yy:"%d ý~éárs"},ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th";return e+n},week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("yo",{months:"Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀".split("_"),monthsShort:"Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀".split("_"),weekdays:"Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta".split("_"),weekdaysShort:"Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá".split("_"),weekdaysMin:"Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Ònì ni] LT",nextDay:"[Ọ̀la ni] LT",nextWeek:"dddd [Ọsẹ̀ tón'bọ] [ni] LT",lastDay:"[Àna ni] LT",lastWeek:"dddd [Ọsẹ̀ tólọ́] [ni] LT",sameElse:"L"},relativeTime:{future:"ní %s",past:"%s kọjá",s:"ìsẹjú aayá die",m:"ìsẹjú kan",mm:"ìsẹjú %d",h:"wákati kan",hh:"wákati %d",d:"ọjọ́ kan",dd:"ọjọ́ %d",M:"osù kan",MM:"osù %d",y:"ọdún kan",yy:"ọdún %d"},ordinalParse:/ọjọ́\s\d{1,2}/,ordinal:"ọjọ́ %d",week:{dow:1,doy:4}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm分",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah点mm分",LLLL:"YYYY年MMMD日ddddAh点mm分",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah点mm分",llll:"YYYY年MMMD日ddddAh点mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){return 12===e&&(e=0),"凌晨"===t||"早上"===t||"上午"===t?e:"下午"===t||"晚上"===t?e+12:e>=11?e:e+12},meridiem:function(e,t,n){var r=100*e+t;return r<600?"凌晨":r<900?"早上":r<1130?"上午":r<1230?"中午":r<1800?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var t,n;return t=e().startOf("week"),n=this.diff(t,"days")>=7?"[下]":"[本]",0===this.minutes()?n+"dddAh点整":n+"dddAh点mm"},lastWeek:function(){var t,n;return t=e().startOf("week"),n=this.unix()=11?e:e+12:"下午"===t||"晚上"===t?e+12:void 0},meridiem:function(e,t,n){var r=100*e+t;return r<600?"凌晨":r<900?"早上":r<1130?"上午":r<1230?"中午":r<1800?"下午":"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},ordinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}});return t})},function(e,t,n){!function(e,t){t(n(1))}(this,function(e){"use strict";var t=e.defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah點mm分",LTS:"Ah點m分s秒",L:"YYYY年MMMD日",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah點mm分",LLLL:"YYYY年MMMD日ddddAh點mm分",l:"YYYY年MMMD日",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah點mm分",llll:"YYYY年MMMD日ddddAh點mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){return 12===e&&(e=0),"凌晨"===t||"早上"===t||"上午"===t?e:"中午"===t?e>=11?e:e+12:"下午"===t||"晚上"===t?e+12:void 0},meridiem:function(e,t,n){var r=100*e+t;return r<600?"凌晨":r<900?"早上":r<1130?"上午":r<1230?"中午":r<1800?"下午":"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},ordinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}});return t})},function(e,t,n){"use strict";function r(){}function a(e){try{return e.then}catch(e){return y=e,M}}function i(e,t){try{return e(t)}catch(e){return y=e,M}}function o(e,t,n){try{e(t,n)}catch(e){return y=e,M}}function s(e){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._45=0,this._81=0,this._65=null,this._54=null,e!==r&&p(e,this)}function u(e,t,n){return new e.constructor(function(a,i){var o=new s(r);o.then(a,i),d(e,new h(t,n,o))})}function d(e,t){for(;3===e._81;)e=e._65;return s._10&&s._10(e),0===e._81?0===e._45?(e._45=1,void(e._54=t)):1===e._45?(e._45=2,void(e._54=[e._54,t])):void e._54.push(t):void l(e,t)}function l(e,t){f(function(){var n=1===e._81?t.onFulfilled:t.onRejected;if(null===n)return void(1===e._81?c(t.promise,e._65):_(t.promise,e._65));var r=i(n,e._65);r===M?_(t.promise,y):c(t.promise,r)})}function c(e,t){if(t===e)return _(e,new TypeError("A promise cannot be resolved with itself."));if(t&&("object"==typeof t||"function"==typeof t)){var n=a(t);if(n===M)return _(e,y);if(n===e.then&&t instanceof s)return e._81=3,e._65=t,void m(e);if("function"==typeof n)return void p(n.bind(t),e)}e._81=1,e._65=t,m(e)}function _(e,t){e._81=2,e._65=t,s._97&&s._97(e,t),m(e)}function m(e){if(1===e._45&&(d(e,e._54),e._54=null),2===e._45){for(var t=0;t.":"function"==typeof t?" Instead of passing a class like Foo, pass React.createElement(Foo) or .":null!=t&&void 0!==t.props?" This may be caused by unintentionally loading two independent copies of React.":"");var o,s=f.createElement(R,{child:t});if(e){var u=Y.get(e);o=u._processChildContext(u._context)}else o=T;var l=_(n);if(l){var c=l._currentElement,h=c.props.child;if(E(h,t)){var p=l._renderedComponent.getPublicInstance(),y=r&&function(){r.call(p)};return I._updateRootComponent(l,s,o,n,y),p}I.unmountComponentAtNode(n)}var M=a(n),v=M&&!!i(M),g=d(n),L=v&&!l&&!g,k=I._renderNewRootComponent(s,n,L,o)._renderedComponent.getPublicInstance();return r&&r.call(k),k},render:function(e,t,n){return I._renderSubtreeIntoContainer(null,e,t,n)},unmountComponentAtNode:function(e){l(e)?void 0:m("40");var t=_(e);if(!t){d(e),1===e.nodeType&&e.hasAttribute(C);return!1}return delete O[t._instance.rootID],D.batchedUpdates(u,t,e,!1),!0},_mountImageIntoNode:function(e,t,n,i,o){if(l(t)?void 0:m("41"),i){var s=a(t);if(k.canReuseMarkup(e,s))return void M.precacheNode(n,s);var u=s.getAttribute(k.CHECKSUM_ATTR_NAME);s.removeAttribute(k.CHECKSUM_ATTR_NAME);var d=s.outerHTML;s.setAttribute(k.CHECKSUM_ATTR_NAME,u);var c=e,_=r(c,d),p=" (client) "+c.substring(_-20,_+20)+"\n (server) "+d.substring(_-20,_+20);t.nodeType===H?m("42",p):void 0}if(t.nodeType===H?m("43"):void 0,o.useCreateElement){for(;t.lastChild;)t.removeChild(t.lastChild);h.insertTreeBefore(t,e,null)}else x(t,e),M.precacheNode(n,t.firstChild)}};e.exports=I},function(e,t,n){"use strict";var r=n(4),a=n(21),i=(n(2),{HOST:0,COMPOSITE:1,EMPTY:2,getType:function(e){return null===e||e===!1?i.EMPTY:a.isValidElement(e)?"function"==typeof e.type?i.COMPOSITE:i.HOST:void r("26",e)}});e.exports=i},function(e,t){"use strict";var n={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(e){n.currentScrollLeft=e.x,n.currentScrollTop=e.y}};e.exports=n},function(e,t,n){"use strict";function r(e,t){return null==t?a("30"):void 0,null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}var a=n(4);n(2);e.exports=r},function(e,t){"use strict";function n(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}e.exports=n},function(e,t,n){"use strict";function r(e){for(var t;(t=e._renderedNodeType)===a.COMPOSITE;)e=e._renderedComponent;return t===a.HOST?e._renderedComponent:t===a.EMPTY?null:void 0}var a=n(182);e.exports=r},function(e,t,n){"use strict";function r(){return!i&&a.canUseDOM&&(i="textContent"in document.documentElement?"textContent":"innerText"),i}var a=n(7),i=null;e.exports=r},function(e,t,n){"use strict";function r(e){if(e){var t=e.getName();if(t)return" Check the render method of `"+t+"`."}return""}function a(e){return"function"==typeof e&&"undefined"!=typeof e.prototype&&"function"==typeof e.prototype.mountComponent&&"function"==typeof e.prototype.receiveComponent}function i(e,t){var n;if(null===e||e===!1)n=d.create(i);else if("object"==typeof e){var s=e;!s||"function"!=typeof s.type&&"string"!=typeof s.type?o("130",null==s.type?s.type:typeof s.type,r(s._owner)):void 0,"string"==typeof s.type?n=l.createInternalComponent(s):a(s.type)?(n=new s.type(s),n.getHostNode||(n.getHostNode=n.getNativeNode)):n=new c(s)}else"string"==typeof e||"number"==typeof e?n=l.createInstanceForText(e):o("131",typeof e);return n._mountIndex=0,n._mountImage=null,n}var o=n(4),s=n(5),u=n(264),d=n(177),l=n(179),c=(n(311),n(2),n(3),function(e){this.construct(e)});s(c.prototype,u,{_instantiateReactComponent:i}),e.exports=i},function(e,t){"use strict";function n(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!r[e.type]:"textarea"===t}var r={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};e.exports=n},function(e,t,n){"use strict";var r=n(7),a=n(32),i=n(33),o=function(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(o=function(e,t){return 3===e.nodeType?void(e.nodeValue=t):void i(e,a(t))})),e.exports=o},function(e,t,n){"use strict";function r(e,t){return e&&"object"==typeof e&&null!=e.key?d.escape(e.key):t.toString(36)}function a(e,t,n,i){var _=typeof e;if("undefined"!==_&&"boolean"!==_||(e=null),null===e||"string"===_||"number"===_||"object"===_&&e.$$typeof===s)return n(i,e,""===t?l+r(e,0):t),1;var m,h,p=0,f=""===t?l:t+c;if(Array.isArray(e))for(var y=0;yl){for(var t=0,n=s.length-d;t>8-s%1*8)){if(r=i.charCodeAt(s+=.75),r>255)throw new n;t=t<<8|r}return o}var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";n.prototype=new Error,n.prototype.code=5,n.prototype.name="InvalidCharacterError",e.exports=r},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var a=n(8);e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(a.isURLSearchParams(t))i=t.toString();else{var o=[];a.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(a.isArray(e)&&(t+="[]"),a.isArray(e)||(e=[e]),a.forEach(e,function(e){a.isDate(e)?e=e.toISOString():a.isObject(e)&&(e=JSON.stringify(e)),o.push(r(t)+"="+r(e))}))}),i=o.join("&")}return i&&(e+=(e.indexOf("?")===-1?"?":"&")+i),e}},function(e,t){"use strict";e.exports=function(e,t){return e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,"")}},function(e,t,n){"use strict";var r=n(8);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,a,i,o){var s=[];s.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),r.isString(a)&&s.push("path="+a),r.isString(i)&&s.push("domain="+i),o===!0&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t,n){"use strict";var r=n(8);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(a.setAttribute("href",t),t=a.href),a.setAttribute("href",t),{href:a.href,protocol:a.protocol?a.protocol.replace(/:$/,""):"",host:a.host,search:a.search?a.search.replace(/^\?/,""):"",hash:a.hash?a.hash.replace(/^#/,""):"",hostname:a.hostname,port:a.port,pathname:"/"===a.pathname.charAt(0)?a.pathname:"/"+a.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),a=document.createElement("a");return t=e(window.location.href),function(n){var a=r.isString(n)?e(n):n;return a.protocol===t.protocol&&a.host===t.host}}():function(){return function(){return!0}}()},function(e,t,n){"use strict";var r=n(8);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(8);e.exports=function(e){var t,n,a,i={};return e?(r.forEach(e.split("\n"),function(e){a=e.indexOf(":"),t=r.trim(e.substr(0,a)).toLowerCase(),n=r.trim(e.substr(a+1)),t&&(i[t]=i[t]?i[t]+", "+n:n)}),i):i}},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n=0;n--)t.push(d.default.createElement("p",{key:n},e[n]));return t}}},{key:"render",value:function(){return d.default.createElement("div",{className:"EventMessages"},this.getMessages())}}]),t}(u.Component);t.default=l},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n=0;r--){var a=n[r];e.push(d.default.createElement(p.default,{event:a,key:r,alignment:r%2===0?"left":"right"},d.default.createElement(L.default,{event:a})));var i=this.getDate(a.timestamp),o="";r>0&&(o=this.getDate(n[r-1].timestamp)),o!==i&&i!==t&&(e.push(d.default.createElement(y.default,{date:i,key:i,first:0===r})),t=i)}return e}},{key:"render",value:function(){return this.state.loaded?this.state.error?d.default.createElement("div",{className:"Timeline"},d.default.createElement("div",{className:"status-message"},"Unable to connect to ",this.state.host)):d.default.createElement("div",{className:"Timeline"},d.default.createElement("div",{className:"primary-view"},this.getTimelineObjects()),d.default.createElement(b.default,{wsIsOpen:this.state.wsIsOpen,wsIsRecovering:this.state.wsIsRecovering,wsURI:this.state.wsURI,wsIsAuthenticated:this.state.wsIsAuthenticated})):d.default.createElement("div",{className:"Timeline"},d.default.createElement("div",{className:"status-message"},"Connecting to ",this.state.host,".."))}}]),t}(u.Component);t.default=D},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}var a=n(14),i=r(a),o=n(251),s=r(o),u=n(217),d=r(u);n(235),s.default.render(i.default.createElement(d.default,null),document.getElementById("root"))},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,".App .view-container{padding-top:.75rem;padding-left:11rem}.App .primary-view{width:100%;max-width:450px}.App .insecure-scheme{width:100%;text-align:center;margin:0 auto;font-family:Lato,sans-serif;font-weight:300;position:absolute;top:40%;margin-top:-1rem}",""])},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,'.DateNode{position:relative;height:4rem}.DateNode .date{background-color:#8e9ab2;border-radius:.3rem;font-family:Roboto,sans-serif;border:.25rem solid #f2f2f2;width:5.5rem;border-radius:.5rem;margin:0;color:#fff;font-size:.8rem;line-height:1.4rem;text-align:center;margin-top:-0.95rem;background:#fff;color:#666;margin:0 auto}@media screen and (min-width:480px){.DateNode .date{position:absolute;top:50%;left:calc(92% - 2.75rem - .25rem)}}@media screen and (min-width:768px){.DateNode .date{left:calc(50% - 2.75rem - .25rem)}}.DateNode.first .date{top:auto;bottom:0}.DateNode .horizontal-line{position:absolute;top:0;width:.25rem;height:100%;background-color:#8e9ab2;content:" ";left:calc(92% - .125rem);display:none}@media screen and (min-width:480px){.DateNode .horizontal-line{display:block}}@media screen and (min-width:768px){.DateNode .horizontal-line{left:calc(50% - .125rem)}}',""])},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,'.EndNode{position:relative;height:4rem;display:none}@media screen and (min-width:480px){.EndNode{display:block}}.EndNode .date{position:absolute;top:0;left:calc(92% - 1.5rem - .25rem);background-color:#8e9ab2;border-radius:.3rem;font-family:Roboto,sans-serif;border:.25rem solid #f2f2f2;width:3rem;height:3rem;border-radius:6rem;margin:0;color:#fff;font-size:.7rem;margin:0 auto;display:none}@media screen and (min-width:480px){.EndNode .date{display:block}}@media screen and (min-width:768px){.EndNode .date{left:calc(50% - 1.5rem - .25rem)}}.EndNode .horizontal-line{position:absolute;top:0;width:.25rem;height:100%;background-color:#8e9ab2;content:" ";left:calc(92% - .125rem);display:none}@media screen and (min-width:480px){.EndNode .horizontal-line{display:block}}@media screen and (min-width:768px){.EndNode .horizontal-line{left:calc(50% - .125rem)}}',""])},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,".EventMessages{font-family:Lato,sans-serif;font-weight:400}.EventMessages p{margin:0;font-size:.8rem;line-height:1.2rem}",""])},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,'.EventNode{position:relative;padding:0 1rem 1rem}@media screen and (min-width:768px){.EventNode{padding:0}}.EventNode .inner{position:relative;background-color:#fff;border-radius:.3rem;box-shadow:0 2px 6px 1px rgba(0,0,0,.125);font-family:Roboto,sans-serif;color:#333;width:100%}@media screen and (min-width:480px){.EventNode .inner{width:83%}}@media screen and (min-width:768px){.EventNode .inner{width:46%}}@media screen and (min-width:768px){.EventNode.right .inner{margin-left:54%}}.EventNode .header{padding:0;border-radius:.25rem .25rem 0 0;position:relative}.EventNode .header .icon{position:absolute;top:.25rem;left:1rem;font-size:2.75rem;color:#fff}.EventNode .header div.icon{top:50%;margin-top:-15px;left:1.5rem}.EventNode .header p.subtitle,.EventNode .header p.title{margin:0;font-family:Lato,sans-serif;color:#fff}.EventNode .header p.title{position:absolute;left:4.5rem;top:.5rem;text-transform:uppercase;font-size:1.5rem;font-weight:300}.EventNode .header p.subtitle{font-size:1rem;font-weight:400;padding-left:4.5rem;padding-top:2.2rem;padding-bottom:.6rem}.EventNode.blue .header{background-color:#46cbde}.EventNode.green .header{background-color:#47dbc3}.EventNode.purple .header{background-color:#e05ee2}.EventNode .body{padding:.75rem 1.5rem}.EventNode .vertical-line{position:absolute;top:2rem;margin-top:-.125rem;width:8.69565%;height:.25rem;background-color:#8e9ab2;content:" "}.EventNode.right .vertical-line{left:-8.69565%;right:auto}.EventNode.left .vertical-line{left:auto;right:-8.69565%}.EventNode .horizontal-line{position:absolute;top:0;width:.25rem;height:100%;background-color:#8e9ab2;content:" ";left:calc(92% - .125rem);display:none}@media screen and (min-width:480px){.EventNode .horizontal-line{display:block}}@media screen and (min-width:768px){.EventNode .horizontal-line{left:calc(50% - .125rem)}}.EventNode .timeline-icon{position:absolute;top:1.75rem;margin-top:-.5rem;width:1rem;height:1rem;border-radius:2rem;background-color:#46cbde;border:.25rem solid #f2f2f2;left:50%;right:auto;margin-left:-.75rem;display:none}@media screen and (min-width:480px){.EventNode .timeline-icon{display:block}}.EventNode.blue .timeline-icon{background-color:#46cbde}.EventNode.green .timeline-icon{background-color:#47dbc3}.EventNode.purple .timeline-icon{background-color:#e05ee2}.EventNode .vertical-arrow{position:absolute;top:2rem;width:.7rem;height:2.1rem;margin-top:-1.05rem;display:none}@media screen and (min-width:480px){.EventNode .vertical-arrow{display:block}}.EventNode.blue .vertical-arrow{fill:#46cbde}.EventNode.green .vertical-arrow{fill:#47dbc3}.EventNode.purple .vertical-arrow{fill:#e05ee2}.EventNode.left .vertical-arrow,.EventNode.right .vertical-arrow{left:auto;right:-.7rem}@media screen and (min-width:768px){.EventNode.right .vertical-arrow{left:-.7rem;right:auto;transform:rotate(180deg)}}.EventNode p.datetime{position:absolute;width:5rem;top:1.5rem;margin:0;font-size:.7rem;line-height:1rem;color:#999}.EventNode.left .datetime{left:auto;right:calc(-1 * 8.69565% * 2 - 5rem);text-align:left}.EventNode.right .datetime{left:calc(-1 * 8.69565% * 2 - 5rem);right:auto;text-align:right}.EventNode .spinner{width:30px;height:30px;background-color:#fff;margin:100px auto;-webkit-animation:sk-rotateplane 1.2s infinite ease-in-out;animation:sk-rotateplane 1.2s infinite ease-in-out}@-webkit-keyframes sk-rotateplane{0%{-webkit-transform:perspective(90px)}50%{-webkit-transform:perspective(90px) rotateY(180deg)}to{-webkit-transform:perspective(90px) rotateY(180deg) rotateX(180deg)}}@keyframes sk-rotateplane{0%{transform:perspective(90px) rotateX(0deg) rotateY(0deg);-webkit-transform:perspective(90px) rotateX(0deg) rotateY(0deg)}50%{transform:perspective(90px) rotateX(-180.1deg) rotateY(0deg);-webkit-transform:perspective(90px) rotateX(-180.1deg) rotateY(0deg)}to{transform:perspective(90px) rotateX(-180deg) rotateY(-179.9deg);-webkit-transform:perspective(90px) rotateX(-180deg) rotateY(-179.9deg)}}',""])},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,".WebSocketStatus{position:absolute;bottom:4rem;right:.3rem;z-index:1010;color:#999;font-size:.8rem;font-family:Roboto,sans-serif}.WebSocketStatus div{display:inline}",""])},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,'.Navigation{position:fixed;bottom:0}.Navigation,.Navigation:after{height:3.7rem;background-color:#282f39;left:0;right:0;z-index:1000}.Navigation:after{background-color:red;position:absolute;bottom:-5rem;content:" "}.Navigation .icon{position:absolute;top:50%;left:1.5rem;margin-top:-.25rem;width:.5rem;height:.5rem;border-radius:2rem;background-color:#bfb;background-color:#333;left:7.25rem}.Navigation .uil-pacman-css{width:30px;height:30px;position:absolute;left:1rem;top:50%;margin-top:-28px;display:none}.Navigation .title{color:#fff;font-size:1.2rem;font-family:Roboto,sans-serif;margin:1rem .75rem;padding:0}',""])},function(e,t,n){t=e.exports=n(15)(),t.push([e.id,".Timeline{padding:.5rem 0 5rem}.Timeline .primary-view{width:100%;max-width:768px;margin:0 auto}.Timeline .status-message{font-family:Lato,sans-serif;font-weight:400;text-align:center;position:absolute;top:50%;left:0;right:0;margin-top:-2.85rem;line-height:2rem}",""])},function(e,t){},function(e,t){"use strict";function n(e){return e.replace(r,function(e,t){return t.toUpperCase()})}var r=/-(.)/g;e.exports=n},function(e,t,n){"use strict";function r(e){return a(e.replace(i,"ms-"))}var a=n(236),i=/^-ms-/;e.exports=r},function(e,t,n){"use strict";function r(e,t){return!(!e||!t)&&(e===t||!a(e)&&(a(t)?r(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}var a=n(246);e.exports=r},function(e,t,n){"use strict";function r(e){var t=e.length;if(Array.isArray(e)||"object"!=typeof e&&"function"!=typeof e?o(!1):void 0,"number"!=typeof t?o(!1):void 0,0===t||t-1 in e?void 0:o(!1),"function"==typeof e.callee?o(!1):void 0,e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(e){}for(var n=Array(t),r=0;r":o.innerHTML="<"+e+">",s[e]=!o.firstChild),s[e]?_[e]:null}var a=n(7),i=n(2),o=a.canUseDOM?document.createElement("div"):null,s={},u=[1,'"],d=[1,"","
"],l=[3,"","
"],c=[1,'',""],_={"*":[1,"?
","
"],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"],param:[1,"",""],tr:[2,"","
"],optgroup:u,option:u,caption:d,colgroup:d,tbody:d,tfoot:d,thead:d,td:l,th:l},m=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];m.forEach(function(e){_[e]=c,s[e]=!0}),e.exports=r},function(e,t){"use strict";function n(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}e.exports=n},function(e,t){"use strict";function n(e){return e.replace(r,"-$1").toLowerCase()}var r=/([A-Z])/g;e.exports=n},function(e,t,n){"use strict";function r(e){return a(e).replace(i,"-ms-")}var a=n(243),i=/^ms-/;e.exports=r},function(e,t){"use strict";function n(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}e.exports=n},function(e,t,n){"use strict";function r(e){return a(e)&&3==e.nodeType}var a=n(245);e.exports=r},function(e,t){"use strict";function n(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}e.exports=n},function(e,t,n){function r(e){return n(a(e))}function a(e){return i[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var i={"./af":63,"./af.js":63,"./ar":69,"./ar-dz":64,"./ar-dz.js":64,"./ar-ly":65,"./ar-ly.js":65,"./ar-ma":66,"./ar-ma.js":66,"./ar-sa":67,"./ar-sa.js":67,"./ar-tn":68,"./ar-tn.js":68,"./ar.js":69,"./az":70,"./az.js":70,"./be":71,"./be.js":71,"./bg":72,"./bg.js":72,"./bn":73,"./bn.js":73,"./bo":74,"./bo.js":74,"./br":75,"./br.js":75,"./bs":76,"./bs.js":76,"./ca":77,"./ca.js":77,"./cs":78,"./cs.js":78,"./cv":79,"./cv.js":79,"./cy":80,"./cy.js":80,"./da":81,"./da.js":81,"./de":83,"./de-at":82,"./de-at.js":82,"./de.js":83,"./dv":84,"./dv.js":84,"./el":85,"./el.js":85,"./en-au":86,"./en-au.js":86,"./en-ca":87,"./en-ca.js":87,"./en-gb":88,"./en-gb.js":88,"./en-ie":89,"./en-ie.js":89,"./en-nz":90,"./en-nz.js":90,"./eo":91,"./eo.js":91,"./es":93,"./es-do":92,"./es-do.js":92,"./es.js":93,"./et":94,"./et.js":94,"./eu":95,"./eu.js":95,"./fa":96,"./fa.js":96,"./fi":97,"./fi.js":97,"./fo":98,"./fo.js":98,"./fr":101,"./fr-ca":99,"./fr-ca.js":99,"./fr-ch":100,"./fr-ch.js":100,"./fr.js":101,"./fy":102,"./fy.js":102,"./gd":103,"./gd.js":103,"./gl":104,"./gl.js":104,"./he":105,"./he.js":105,"./hi":106,"./hi.js":106,"./hr":107,"./hr.js":107,"./hu":108,"./hu.js":108,"./hy-am":109,"./hy-am.js":109,"./id":110,"./id.js":110,"./is":111,"./is.js":111,"./it":112,"./it.js":112,"./ja":113,"./ja.js":113,"./jv":114,"./jv.js":114,"./ka":115,"./ka.js":115,"./kk":116,"./kk.js":116,"./km":117,"./km.js":117,"./ko":118,"./ko.js":118,"./ky":119,"./ky.js":119,"./lb":120,"./lb.js":120,"./lo":121,"./lo.js":121,"./lt":122,"./lt.js":122,"./lv":123,"./lv.js":123,"./me":124,"./me.js":124,"./mi":125,"./mi.js":125,"./mk":126,"./mk.js":126,"./ml":127,"./ml.js":127,"./mr":128,"./mr.js":128,"./ms":130,"./ms-my":129,"./ms-my.js":129,"./ms.js":130,"./my":131,"./my.js":131,"./nb":132,"./nb.js":132,"./ne":133,"./ne.js":133,"./nl":135,"./nl-be":134,"./nl-be.js":134,"./nl.js":135,"./nn":136,"./nn.js":136,"./pa-in":137,"./pa-in.js":137,"./pl":138,"./pl.js":138,"./pt":140,"./pt-br":139,"./pt-br.js":139,"./pt.js":140,"./ro":141,"./ro.js":141,"./ru":142,"./ru.js":142,"./se":143,"./se.js":143,"./si":144,"./si.js":144,"./sk":145,"./sk.js":145,"./sl":146,"./sl.js":146,"./sq":147,"./sq.js":147,"./sr":149,"./sr-cyrl":148,"./sr-cyrl.js":148,"./sr.js":149,"./ss":150,"./ss.js":150,"./sv":151,"./sv.js":151,"./sw":152,"./sw.js":152,"./ta":153,"./ta.js":153,"./te":154,"./te.js":154,"./tet":155,"./tet.js":155,"./th":156,"./th.js":156,"./tl-ph":157,"./tl-ph.js":157,"./tlh":158,"./tlh.js":158,"./tr":159,"./tr.js":159,"./tzl":160,"./tzl.js":160,"./tzm":162,"./tzm-latn":161,"./tzm-latn.js":161,"./tzm.js":162,"./uk":163,"./uk.js":163,"./uz":164,"./uz.js":164,"./vi":165,"./vi.js":165,"./x-pseudo":166,"./x-pseudo.js":166,"./yo":167,"./yo.js":167,"./zh-cn":168,"./zh-cn.js":168,"./zh-hk":169,"./zh-hk.js":169,"./zh-tw":170,"./zh-tw.js":170};r.keys=function(){return Object.keys(i)},r.resolve=a,e.exports=r,r.id=248},function(e,t,n){"use strict";function r(e){var t=new a(a._61);return t._81=1,t._65=e,t}var a=n(171);e.exports=a;var i=r(!0),o=r(!1),s=r(null),u=r(void 0),d=r(0),l=r("");a.resolve=function(e){if(e instanceof a)return e;if(null===e)return s;if(void 0===e)return u;if(e===!0)return i;if(e===!1)return o;if(0===e)return d;if(""===e)return l;if("object"==typeof e||"function"==typeof e)try{var t=e.then;if("function"==typeof t)return new a(t.bind(e))}catch(e){return new a(function(t,n){n(e)})}return r(e)},a.all=function(e){var t=Array.prototype.slice.call(e);return new a(function(e,n){function r(o,s){if(s&&("object"==typeof s||"function"==typeof s)){if(s instanceof a&&s.then===a.prototype.then){for(;3===s._81;)s=s._65;return 1===s._81?r(o,s._65):(2===s._81&&n(s._65),void s.then(function(e){r(o,e)},n))}var u=s.then;if("function"==typeof u){var d=new a(u.bind(s));return void d.then(function(e){r(o,e)},n)}}t[o]=s,0===--i&&e(t)}if(0===t.length)return e([]);for(var i=t.length,o=0;o8&&L<=11),w=32,b=String.fromCharCode(w),D={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["topCompositionEnd","topKeyPress","topTextInput","topPaste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:["topBlur","topCompositionEnd","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:["topBlur","topCompositionStart","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:["topBlur","topCompositionUpdate","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]}},T=!1,S=null,x={eventTypes:D,extractEvents:function(e,t,n,r){return[d(e,t,n,r),_(e,t,n,r)]}};e.exports=x},function(e,t,n){"use strict";var r=n(172),a=n(7),i=(n(10),n(237),n(306)),o=n(244),s=n(247),u=(n(3),s(function(e){return o(e)})),d=!1,l="cssFloat";if(a.canUseDOM){var c=document.createElement("div").style;try{c.font=""}catch(e){d=!0}void 0===document.documentElement.style.cssFloat&&(l="styleFloat")}var _={createMarkupForStyles:function(e,t){var n="";for(var r in e)if(e.hasOwnProperty(r)){var a=e[r];null!=a&&(n+=u(r)+":",n+=i(r,a,t)+";")}return n||null},setValueForStyles:function(e,t,n){var a=e.style;for(var o in t)if(t.hasOwnProperty(o)){var s=i(o,t[o],n);if("float"!==o&&"cssFloat"!==o||(o=l),s)a[o]=s;else{var u=d&&r.shorthandPropertyExpansions[o];if(u)for(var c in u)a[c]="";else a[o]=""}}}};e.exports=_},function(e,t,n){"use strict";function r(e){var t=e.nodeName&&e.nodeName.toLowerCase();return"select"===t||"input"===t&&"file"===e.type}function a(e){var t=k.getPooled(T.change,x,e,w(e));v.accumulateTwoPhaseDispatches(t),Y.batchedUpdates(i,t)}function i(e){M.enqueueEvents(e),M.processEventQueue(!1)}function o(e,t){S=e,x=t,S.attachEvent("onchange",a)}function s(){S&&(S.detachEvent("onchange",a),S=null,x=null)}function u(e,t){if("topChange"===e)return t}function d(e,t,n){"topFocus"===e?(s(),o(t,n)):"topBlur"===e&&s()}function l(e,t){S=e,x=t,E=e.value,j=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(S,"value",H),S.attachEvent?S.attachEvent("onpropertychange",_):S.addEventListener("propertychange",_,!1)}function c(){S&&(delete S.value,S.detachEvent?S.detachEvent("onpropertychange",_):S.removeEventListener("propertychange",_,!1),S=null,x=null,E=null,j=null)}function _(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==E&&(E=t,a(e))}}function m(e,t){if("topInput"===e)return t}function h(e,t,n){"topFocus"===e?(c(),l(t,n)):"topBlur"===e&&c()}function p(e,t){if(("topSelectionChange"===e||"topKeyUp"===e||"topKeyDown"===e)&&S&&S.value!==E)return E=S.value,x}function f(e){return e.nodeName&&"input"===e.nodeName.toLowerCase()&&("checkbox"===e.type||"radio"===e.type)}function y(e,t){if("topClick"===e)return t}var M=n(25),v=n(26),g=n(7),L=n(6),Y=n(11),k=n(12),w=n(49),b=n(50),D=n(189),T={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:["topBlur","topChange","topClick","topFocus","topInput","topKeyDown","topKeyUp","topSelectionChange"]}},S=null,x=null,E=null,j=null,C=!1;g.canUseDOM&&(C=b("change")&&(!document.documentMode||document.documentMode>8));var P=!1;g.canUseDOM&&(P=b("input")&&(!document.documentMode||document.documentMode>11));var H={get:function(){return j.get.call(this)},set:function(e){E=""+e,j.set.call(this,e)}},A={eventTypes:T,extractEvents:function(e,t,n,a){var i,o,s=t?L.getNodeFromInstance(t):window;if(r(s)?C?i=u:o=d:D(s)?P?i=m:(i=p,o=h):f(s)&&(i=y),i){var l=i(e,t);if(l){var c=k.getPooled(T.change,l,n,a);return c.type="change",v.accumulateTwoPhaseDispatches(c),c}}o&&o(e,s,t)}};e.exports=A},function(e,t,n){"use strict";var r=n(4),a=n(18),i=n(7),o=n(240),s=n(9),u=(n(2),{dangerouslyReplaceNodeWithMarkup:function(e,t){if(i.canUseDOM?void 0:r("56"),t?void 0:r("57"),"HTML"===e.nodeName?r("58"):void 0,"string"==typeof t){var n=o(t,s)[0];e.parentNode.replaceChild(n,e)}else a.replaceChildWithTree(e,t)}});e.exports=u},function(e,t){"use strict";var n=["ResponderEventPlugin","SimpleEventPlugin","TapEventPlugin","EnterLeaveEventPlugin","ChangeEventPlugin","SelectEventPlugin","BeforeInputEventPlugin"];e.exports=n},function(e,t,n){"use strict";var r=n(26),a=n(6),i=n(30),o={mouseEnter:{registrationName:"onMouseEnter", +dependencies:["topMouseOut","topMouseOver"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["topMouseOut","topMouseOver"]}},s={eventTypes:o,extractEvents:function(e,t,n,s){if("topMouseOver"===e&&(n.relatedTarget||n.fromElement))return null;if("topMouseOut"!==e&&"topMouseOver"!==e)return null;var u;if(s.window===s)u=s;else{var d=s.ownerDocument;u=d?d.defaultView||d.parentWindow:window}var l,c;if("topMouseOut"===e){l=t;var _=n.relatedTarget||n.toElement;c=_?a.getClosestInstanceFromNode(_):null}else l=null,c=t;if(l===c)return null;var m=null==l?u:a.getNodeFromInstance(l),h=null==c?u:a.getNodeFromInstance(c),p=i.getPooled(o.mouseLeave,l,n,s);p.type="mouseleave",p.target=m,p.relatedTarget=h;var f=i.getPooled(o.mouseEnter,c,n,s);return f.type="mouseenter",f.target=h,f.relatedTarget=m,r.accumulateEnterLeaveDispatches(p,f,l,c),[p,f]}};e.exports=s},function(e,t,n){"use strict";function r(e){this._root=e,this._startText=this.getText(),this._fallbackText=null}var a=n(5),i=n(17),o=n(187);a(r.prototype,{destructor:function(){this._root=null,this._startText=null,this._fallbackText=null},getText:function(){return"value"in this._root?this._root.value:this._root[o()]},getData:function(){if(this._fallbackText)return this._fallbackText;var e,t,n=this._startText,r=n.length,a=this.getText(),i=a.length;for(e=0;e1?1-t:void 0;return this._fallbackText=a.slice(e,s),this._fallbackText}}),i.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";var r=n(19),a=r.injection.MUST_USE_PROPERTY,i=r.injection.HAS_BOOLEAN_VALUE,o=r.injection.HAS_NUMERIC_VALUE,s=r.injection.HAS_POSITIVE_NUMERIC_VALUE,u=r.injection.HAS_OVERLOADED_BOOLEAN_VALUE,d={isCustomAttribute:RegExp.prototype.test.bind(new RegExp("^(data|aria)-["+r.ATTRIBUTE_NAME_CHAR+"]*$")),Properties:{accept:0,acceptCharset:0,accessKey:0,action:0,allowFullScreen:i,allowTransparency:0,alt:0,as:0,async:i,autoComplete:0,autoPlay:i,capture:i,cellPadding:0,cellSpacing:0,charSet:0,challenge:0,checked:a|i,cite:0,classID:0,className:0,cols:s,colSpan:0,content:0,contentEditable:0,contextMenu:0,controls:i,coords:0,crossOrigin:0,data:0,dateTime:0,default:i,defer:i,dir:0,disabled:i,download:u,draggable:0,encType:0,form:0,formAction:0,formEncType:0,formMethod:0,formNoValidate:i,formTarget:0,frameBorder:0,headers:0,height:0,hidden:i,high:0,href:0,hrefLang:0,htmlFor:0,httpEquiv:0,icon:0,id:0,inputMode:0,integrity:0,is:0,keyParams:0,keyType:0,kind:0,label:0,lang:0,list:0,loop:i,low:0,manifest:0,marginHeight:0,marginWidth:0,max:0,maxLength:0,media:0,mediaGroup:0,method:0,min:0,minLength:0,multiple:a|i,muted:a|i,name:0,nonce:0,noValidate:i,open:i,optimum:0,pattern:0,placeholder:0,playsInline:i,poster:0,preload:0,profile:0,radioGroup:0,readOnly:i,referrerPolicy:0,rel:0,required:i,reversed:i,role:0,rows:s,rowSpan:o,sandbox:0,scope:0,scoped:i,scrolling:0,seamless:i,selected:a|i,shape:0,size:s,sizes:0,span:s,spellCheck:0,src:0,srcDoc:0,srcLang:0,srcSet:0,start:o,step:0,style:0,summary:0,tabIndex:0,target:0,title:0,type:0,useMap:0,value:0,width:0,wmode:0,wrap:0,about:0,datatype:0,inlist:0,prefix:0,property:0,resource:0,typeof:0,vocab:0,autoCapitalize:0,autoCorrect:0,autoSave:0,color:0,itemProp:0,itemScope:i,itemType:0,itemID:0,itemRef:0,results:0,security:0,unselectable:0},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{}};e.exports=d},function(e,t,n){(function(t){"use strict";function r(e,t,n,r){var a=void 0===e[n];null!=t&&a&&(e[n]=i(t,!0))}var a=n(20),i=n(188),o=(n(41),n(51)),s=n(191),u=(n(3),{instantiateChildren:function(e,t,n,a){if(null==e)return null;var i={};return s(e,r,i),i},updateChildren:function(e,t,n,r,s,u,d,l,c){if(t||e){var _,m;for(_ in t)if(t.hasOwnProperty(_)){m=e&&e[_];var h=m&&m._currentElement,p=t[_];if(null!=m&&o(h,p))a.receiveComponent(m,p,s,l),t[_]=m;else{m&&(r[_]=a.getHostNode(m),a.unmountComponent(m,!1));var f=i(p,!0);t[_]=f;var y=a.mountComponent(f,s,u,d,l,c);n.push(y)}}for(_ in e)!e.hasOwnProperty(_)||t&&t.hasOwnProperty(_)||(m=e[_],r[_]=a.getHostNode(m),a.unmountComponent(m,!1))}},unmountChildren:function(e,t){for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];a.unmountComponent(r,t)}}});e.exports=u}).call(t,n(36))},function(e,t,n){"use strict";var r=n(37),a=n(270),i={processChildrenUpdates:a.dangerouslyProcessChildrenUpdates,replaceNodeWithMarkup:r.dangerouslyReplaceNodeWithMarkup};e.exports=i},function(e,t,n){"use strict";function r(e){}function a(e,t){}function i(e){return!(!e.prototype||!e.prototype.isReactComponent)}function o(e){return!(!e.prototype||!e.prototype.isPureReactComponent)}var s=n(4),u=n(5),d=n(21),l=n(43),c=n(13),_=n(44),m=n(27),h=(n(10),n(182)),p=n(20),f=n(24),y=(n(2),n(35)),M=n(51),v=(n(3),{ImpureClass:0,PureClass:1,StatelessFunctional:2});r.prototype.render=function(){var e=m.get(this)._currentElement.type,t=e(this.props,this.context,this.updater);return a(e,t),t};var g=1,L={construct:function(e){this._currentElement=e,this._rootNodeID=0,this._compositeType=null,this._instance=null,this._hostParent=null,this._hostContainerInfo=null,this._updateBatchNumber=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedNodeType=null,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._topLevelWrapper=null,this._pendingCallbacks=null,this._calledComponentWillUnmount=!1},mountComponent:function(e,t,n,u){this._context=u,this._mountOrder=g++,this._hostParent=t,this._hostContainerInfo=n;var l,c=this._currentElement.props,_=this._processContext(u),h=this._currentElement.type,p=e.getUpdateQueue(),y=i(h),M=this._constructComponent(y,c,_,p);y||null!=M&&null!=M.render?o(h)?this._compositeType=v.PureClass:this._compositeType=v.ImpureClass:(l=M,a(h,l),null===M||M===!1||d.isValidElement(M)?void 0:s("105",h.displayName||h.name||"Component"),M=new r(h),this._compositeType=v.StatelessFunctional);M.props=c,M.context=_,M.refs=f,M.updater=p,this._instance=M,m.set(M,this);var L=M.state;void 0===L&&(M.state=L=null),"object"!=typeof L||Array.isArray(L)?s("106",this.getName()||"ReactCompositeComponent"):void 0,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1;var Y;return Y=M.unstable_handleError?this.performInitialMountWithErrorHandling(l,t,n,e,u):this.performInitialMount(l,t,n,e,u),M.componentDidMount&&e.getReactMountReady().enqueue(M.componentDidMount,M),Y},_constructComponent:function(e,t,n,r){return this._constructComponentWithoutOwner(e,t,n,r)},_constructComponentWithoutOwner:function(e,t,n,r){var a=this._currentElement.type;return e?new a(t,n,r):a(t,n,r)},performInitialMountWithErrorHandling:function(e,t,n,r,a){var i,o=r.checkpoint();try{i=this.performInitialMount(e,t,n,r,a)}catch(s){r.rollback(o),this._instance.unstable_handleError(s),this._pendingStateQueue&&(this._instance.state=this._processPendingState(this._instance.props,this._instance.context)),o=r.checkpoint(),this._renderedComponent.unmountComponent(!0),r.rollback(o),i=this.performInitialMount(e,t,n,r,a)}return i},performInitialMount:function(e,t,n,r,a){var i=this._instance,o=0;i.componentWillMount&&(i.componentWillMount(),this._pendingStateQueue&&(i.state=this._processPendingState(i.props,i.context))),void 0===e&&(e=this._renderValidatedComponent());var s=h.getType(e);this._renderedNodeType=s;var u=this._instantiateReactComponent(e,s!==h.EMPTY);this._renderedComponent=u;var d=p.mountComponent(u,r,t,n,this._processChildContext(a),o);return d},getHostNode:function(){return p.getHostNode(this._renderedComponent)},unmountComponent:function(e){if(this._renderedComponent){var t=this._instance;if(t.componentWillUnmount&&!t._calledComponentWillUnmount)if(t._calledComponentWillUnmount=!0,e){var n=this.getName()+".componentWillUnmount()";_.invokeGuardedCallback(n,t.componentWillUnmount.bind(t))}else t.componentWillUnmount();this._renderedComponent&&(p.unmountComponent(this._renderedComponent,e),this._renderedNodeType=null,this._renderedComponent=null,this._instance=null),this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=0,this._topLevelWrapper=null,m.remove(t)}},_maskContext:function(e){var t=this._currentElement.type,n=t.contextTypes;if(!n)return f;var r={};for(var a in n)r[a]=e[a];return r},_processContext:function(e){var t=this._maskContext(e);return t},_processChildContext:function(e){var t,n=this._currentElement.type,r=this._instance;if(r.getChildContext&&(t=r.getChildContext()),t){"object"!=typeof n.childContextTypes?s("107",this.getName()||"ReactCompositeComponent"):void 0;for(var a in t)a in n.childContextTypes?void 0:s("108",this.getName()||"ReactCompositeComponent",a);return u({},e,t)}return e},_checkContextTypes:function(e,t,n){},receiveComponent:function(e,t,n){var r=this._currentElement,a=this._context;this._pendingElement=null,this.updateComponent(t,r,e,a,n)},performUpdateIfNecessary:function(e){null!=this._pendingElement?p.receiveComponent(this,this._pendingElement,e,this._context):null!==this._pendingStateQueue||this._pendingForceUpdate?this.updateComponent(e,this._currentElement,this._currentElement,this._context,this._context):this._updateBatchNumber=null},updateComponent:function(e,t,n,r,a){var i=this._instance;null==i?s("136",this.getName()||"ReactCompositeComponent"):void 0;var o,u=!1;this._context===a?o=i.context:(o=this._processContext(a),u=!0);var d=t.props,l=n.props;t!==n&&(u=!0),u&&i.componentWillReceiveProps&&i.componentWillReceiveProps(l,o);var c=this._processPendingState(l,o),_=!0;this._pendingForceUpdate||(i.shouldComponentUpdate?_=i.shouldComponentUpdate(l,c,o):this._compositeType===v.PureClass&&(_=!y(d,l)||!y(i.state,c))),this._updateBatchNumber=null,_?(this._pendingForceUpdate=!1,this._performComponentUpdate(n,l,c,o,e,a)):(this._currentElement=n,this._context=a,i.props=l,i.state=c,i.context=o)},_processPendingState:function(e,t){var n=this._instance,r=this._pendingStateQueue,a=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!r)return n.state;if(a&&1===r.length)return r[0];for(var i=u({},a?r[0]:n.state),o=a?1:0;o=0||null!=t.is}function h(e){var t=e.type;_(t),this._currentElement=e,this._tag=t.toLowerCase(),this._namespaceURI=null,this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._hostNode=null,this._hostParent=null,this._rootNodeID=0,this._domID=0,this._hostContainerInfo=null,this._wrapperState=null,this._topLevelWrapper=null,this._flags=0}var p=n(4),f=n(5),y=n(253),M=n(255),v=n(18),g=n(38),L=n(19),Y=n(174),k=n(25),w=n(39),b=n(29),D=n(175),T=n(6),S=n(271),x=n(272),E=n(176),j=n(275),C=(n(10),n(284)),P=n(289),H=(n(9),n(32)),A=(n(2),n(50),n(35),n(52),n(3),D),O=k.deleteListener,N=T.getNodeFromInstance,R=b.listenTo,I=w.registrationNameModules,W={string:!0,number:!0},F="style",U="__html",z={children:null,dangerouslySetInnerHTML:null,suppressContentEditableWarning:null},B=11,V={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},J={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},q={listing:!0,pre:!0,textarea:!0},G=f({menuitem:!0},J),K=/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/,$={},X={}.hasOwnProperty,Q=1;h.displayName="ReactDOMComponent",h.Mixin={mountComponent:function(e,t,n,r){this._rootNodeID=Q++,this._domID=n._idCounter++,this._hostParent=t,this._hostContainerInfo=n;var i=this._currentElement.props;switch(this._tag){case"audio":case"form":case"iframe":case"img":case"link":case"object":case"source":case"video":this._wrapperState={listeners:null},e.getReactMountReady().enqueue(l,this);break;case"input":S.mountWrapper(this,i,t),i=S.getHostProps(this,i),e.getReactMountReady().enqueue(l,this);break;case"option":x.mountWrapper(this,i,t),i=x.getHostProps(this,i);break;case"select":E.mountWrapper(this,i,t),i=E.getHostProps(this,i),e.getReactMountReady().enqueue(l,this);break;case"textarea":j.mountWrapper(this,i,t),i=j.getHostProps(this,i),e.getReactMountReady().enqueue(l,this)}a(this,i);var o,c;null!=t?(o=t._namespaceURI,c=t._tag):n._tag&&(o=n._namespaceURI,c=n._tag),(null==o||o===g.svg&&"foreignobject"===c)&&(o=g.html),o===g.html&&("svg"===this._tag?o=g.svg:"math"===this._tag&&(o=g.mathml)),this._namespaceURI=o;var _;if(e.useCreateElement){var m,h=n._ownerDocument;if(o===g.html)if("script"===this._tag){var p=h.createElement("div"),f=this._currentElement.type;p.innerHTML="<"+f+">",m=p.removeChild(p.firstChild)}else m=i.is?h.createElement(this._currentElement.type,i.is):h.createElement(this._currentElement.type);else m=h.createElementNS(o,this._currentElement.type);T.precacheNode(this,m),this._flags|=A.hasCachedChildNodes,this._hostParent||Y.setAttributeForRoot(m),this._updateDOMProperties(null,i,e);var M=v(m);this._createInitialChildren(e,i,r,M),_=M}else{var L=this._createOpenTagMarkupAndPutListeners(e,i),k=this._createContentMarkup(e,i,r);_=!k&&J[this._tag]?L+"/>":L+">"+k+""}switch(this._tag){case"input":e.getReactMountReady().enqueue(s,this),i.autoFocus&&e.getReactMountReady().enqueue(y.focusDOMComponent,this);break;case"textarea":e.getReactMountReady().enqueue(u,this),i.autoFocus&&e.getReactMountReady().enqueue(y.focusDOMComponent,this);break;case"select":i.autoFocus&&e.getReactMountReady().enqueue(y.focusDOMComponent,this);break;case"button":i.autoFocus&&e.getReactMountReady().enqueue(y.focusDOMComponent,this);break;case"option":e.getReactMountReady().enqueue(d,this)}return _},_createOpenTagMarkupAndPutListeners:function(e,t){var n="<"+this._currentElement.type;for(var r in t)if(t.hasOwnProperty(r)){var a=t[r];if(null!=a)if(I.hasOwnProperty(r))a&&i(this,r,a,e);else{r===F&&(a&&(a=this._previousStyleCopy=f({},t.style)),a=M.createMarkupForStyles(a,this));var o=null;null!=this._tag&&m(this._tag,t)?z.hasOwnProperty(r)||(o=Y.createMarkupForCustomAttribute(r,a)):o=Y.createMarkupForProperty(r,a),o&&(n+=" "+o)}}return e.renderToStaticMarkup?n:(this._hostParent||(n+=" "+Y.createMarkupForRoot()),n+=" "+Y.createMarkupForID(this._domID))},_createContentMarkup:function(e,t,n){var r="",a=t.dangerouslySetInnerHTML;if(null!=a)null!=a.__html&&(r=a.__html);else{var i=W[typeof t.children]?t.children:null,o=null!=i?null:t.children;if(null!=i)r=H(i);else if(null!=o){var s=this.mountChildren(o,e,n);r=s.join("")}}return q[this._tag]&&"\n"===r.charAt(0)?"\n"+r:r},_createInitialChildren:function(e,t,n,r){var a=t.dangerouslySetInnerHTML;if(null!=a)null!=a.__html&&v.queueHTML(r,a.__html);else{var i=W[typeof t.children]?t.children:null,o=null!=i?null:t.children;if(null!=i)v.queueText(r,i);else if(null!=o)for(var s=this.mountChildren(o,e,n),u=0;u"},receiveComponent:function(){},getHostNode:function(){return i.getNodeFromInstance(this)},unmountComponent:function(){i.uncacheNode(this)}}),e.exports=o},function(e,t){"use strict";var n={useCreateElement:!0,useFiber:!1};e.exports=n},function(e,t,n){"use strict";var r=n(37),a=n(6),i={dangerouslyProcessChildrenUpdates:function(e,t){var n=a.getNodeFromInstance(e);r.processUpdates(n,t)}};e.exports=i},function(e,t,n){"use strict";function r(){this._rootNodeID&&c.updateWrapper(this)}function a(e){var t=this._currentElement.props,n=u.executeOnChange(t,e);l.asap(r,this);var a=t.name;if("radio"===t.type&&null!=a){for(var o=d.getNodeFromInstance(this),s=o;s.parentNode;)s=s.parentNode;for(var c=s.querySelectorAll("input[name="+JSON.stringify(""+a)+'][type="radio"]'),_=0;_t.end?(n=t.end,r=t.start):(n=t.start,r=t.end),a.moveToElementText(e),a.moveStart("character",n),a.setEndPoint("EndToStart",a),a.moveEnd("character",r-n),a.select()}function s(e,t){if(window.getSelection){var n=window.getSelection(),r=e[l()].length,a=Math.min(t.start,r),i=void 0===t.end?a:Math.min(t.end,r);if(!n.extend&&a>i){var o=i;i=a,a=o}var s=d(e,a),u=d(e,i);if(s&&u){var c=document.createRange();c.setStart(s.node,s.offset),n.removeAllRanges(),a>i?(n.addRange(c),n.extend(u.node,u.offset)):(c.setEnd(u.node,u.offset),n.addRange(c))}}}var u=n(7),d=n(312),l=n(187),c=u.canUseDOM&&"selection"in document&&!("getSelection"in window),_={getOffsets:c?a:i,setOffsets:c?o:s};e.exports=_},function(e,t,n){"use strict";var r=n(4),a=n(5),i=n(37),o=n(18),s=n(6),u=n(32),d=(n(2),n(52),function(e){this._currentElement=e,this._stringText=""+e,this._hostNode=null,this._hostParent=null,this._domID=0,this._mountIndex=0,this._closingComment=null,this._commentNodes=null});a(d.prototype,{mountComponent:function(e,t,n,r){var a=n._idCounter++,i=" react-text: "+a+" ",d=" /react-text ";if(this._domID=a,this._hostParent=t,e.useCreateElement){var l=n._ownerDocument,c=l.createComment(i),_=l.createComment(d),m=o(l.createDocumentFragment());return o.queueChild(m,o(c)),this._stringText&&o.queueChild(m,o(l.createTextNode(this._stringText))),o.queueChild(m,o(_)),s.precacheNode(this,c),this._closingComment=_,m}var h=u(this._stringText);return e.renderToStaticMarkup?h:""+h+""},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;if(n!==this._stringText){this._stringText=n;var r=this.getHostNode();i.replaceDelimitedText(r[0],r[1],n)}}},getHostNode:function(){var e=this._commentNodes;if(e)return e;if(!this._closingComment)for(var t=s.getNodeFromInstance(this),n=t.nextSibling;;){if(null==n?r("67",this._domID):void 0,8===n.nodeType&&" /react-text "===n.nodeValue){this._closingComment=n;break}n=n.nextSibling}return e=[this._hostNode,this._closingComment],this._commentNodes=e,e},unmountComponent:function(){this._closingComment=null,this._commentNodes=null,s.uncacheNode(this)}}),e.exports=d},function(e,t,n){"use strict";function r(){this._rootNodeID&&l.updateWrapper(this)}function a(e){var t=this._currentElement.props,n=s.executeOnChange(t,e);return d.asap(r,this),n}var i=n(4),o=n(5),s=n(42),u=n(6),d=n(11),l=(n(2),n(3),{getHostProps:function(e,t){null!=t.dangerouslySetInnerHTML?i("91"):void 0;var n=o({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue,onChange:e._wrapperState.onChange});return n},mountWrapper:function(e,t){var n=s.getValue(t),r=n;if(null==n){var o=t.defaultValue,u=t.children;null!=u&&(null!=o?i("92"):void 0,Array.isArray(u)&&(u.length<=1?void 0:i("93"),u=u[0]),o=""+u),null==o&&(o=""),r=o}e._wrapperState={initialValue:""+r,listeners:null,onChange:a.bind(e)}},updateWrapper:function(e){var t=e._currentElement.props,n=u.getNodeFromInstance(e),r=s.getValue(t);if(null!=r){var a=""+r;a!==n.value&&(n.value=a),null==t.defaultValue&&(n.defaultValue=a)}null!=t.defaultValue&&(n.defaultValue=t.defaultValue)},postMountWrapper:function(e){var t=u.getNodeFromInstance(e);t.value=t.textContent}});e.exports=l},function(e,t,n){"use strict";function r(e,t){"_hostNode"in e?void 0:u("33"),"_hostNode"in t?void 0:u("33");for(var n=0,r=e;r;r=r._hostParent)n++;for(var a=0,i=t;i;i=i._hostParent)a++;for(;n-a>0;)e=e._hostParent,n--;for(;a-n>0;)t=t._hostParent,a--;for(var o=n;o--;){if(e===t)return e;e=e._hostParent,t=t._hostParent}return null}function a(e,t){"_hostNode"in e?void 0:u("35"),"_hostNode"in t?void 0:u("35");for(;t;){if(t===e)return!0;t=t._hostParent}return!1}function i(e){return"_hostNode"in e?void 0:u("36"),e._hostParent}function o(e,t,n){for(var r=[];e;)r.push(e),e=e._hostParent;var a;for(a=r.length;a-- >0;)t(r[a],"captured",n);for(a=0;a0;)n(u[d],"captured",i)}var u=n(4);n(2);e.exports={isAncestor:a,getLowestCommonAncestor:r,getParentInstance:i,traverseTwoPhase:o, +traverseEnterLeave:s}},function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var a=n(5),i=n(11),o=n(31),s=n(9),u={initialize:s,close:function(){_.isBatchingUpdates=!1}},d={initialize:s,close:i.flushBatchedUpdates.bind(i)},l=[d,u];a(r.prototype,o,{getTransactionWrappers:function(){return l}});var c=new r,_={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,a,i){var o=_.isBatchingUpdates;return _.isBatchingUpdates=!0,o?e(t,n,r,a,i):c.perform(e,null,t,n,r,a,i)}};e.exports=_},function(e,t,n){"use strict";function r(){k||(k=!0,M.EventEmitter.injectReactEventListener(y),M.EventPluginHub.injectEventPluginOrder(s),M.EventPluginUtils.injectComponentTree(_),M.EventPluginUtils.injectTreeTraversal(h),M.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:Y,EnterLeaveEventPlugin:u,ChangeEventPlugin:o,SelectEventPlugin:L,BeforeInputEventPlugin:i}),M.HostComponent.injectGenericComponentClass(c),M.HostComponent.injectTextComponentClass(p),M.DOMProperty.injectDOMPropertyConfig(a),M.DOMProperty.injectDOMPropertyConfig(d),M.DOMProperty.injectDOMPropertyConfig(g),M.EmptyComponent.injectEmptyComponentFactory(function(e){return new m(e)}),M.Updates.injectReconcileTransaction(v),M.Updates.injectBatchingStrategy(f),M.Component.injectEnvironment(l))}var a=n(252),i=n(254),o=n(256),s=n(258),u=n(259),d=n(261),l=n(263),c=n(266),_=n(6),m=n(268),h=n(276),p=n(274),f=n(277),y=n(281),M=n(282),v=n(287),g=n(292),L=n(293),Y=n(294),k=!1;e.exports={inject:r}},193,function(e,t,n){"use strict";function r(e){a.enqueueEvents(e),a.processEventQueue(!1)}var a=n(25),i={handleTopLevel:function(e,t,n,i){var o=a.extractEvents(e,t,n,i);r(o)}};e.exports=i},function(e,t,n){"use strict";function r(e){for(;e._hostParent;)e=e._hostParent;var t=c.getNodeFromInstance(e),n=t.parentNode;return c.getClosestInstanceFromNode(n)}function a(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}function i(e){var t=m(e.nativeEvent),n=c.getClosestInstanceFromNode(t),a=n;do e.ancestors.push(a),a=a&&r(a);while(a);for(var i=0;i/,i=/^<\!\-\-/,o={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return i.test(e)?e:e.replace(a," "+o.CHECKSUM_ATTR_NAME+'="'+t+'"$&')},canReuseMarkup:function(e,t){var n=t.getAttribute(o.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var a=r(e);return a===n}};e.exports=o},function(e,t,n){"use strict";function r(e,t,n){return{type:"INSERT_MARKUP",content:e,fromIndex:null,fromNode:null,toIndex:n,afterNode:t}}function a(e,t,n){return{type:"MOVE_EXISTING",content:null,fromIndex:e._mountIndex,fromNode:_.getHostNode(e),toIndex:n,afterNode:t}}function i(e,t){return{type:"REMOVE_NODE",content:null,fromIndex:e._mountIndex,fromNode:t,toIndex:null,afterNode:null}}function o(e){return{type:"SET_MARKUP",content:e,fromIndex:null,fromNode:null,toIndex:null,afterNode:null}}function s(e){return{type:"TEXT_CONTENT",content:e,fromIndex:null,fromNode:null,toIndex:null,afterNode:null}}function u(e,t){return t&&(e=e||[],e.push(t)),e}function d(e,t){c.processChildrenUpdates(e,t)}var l=n(4),c=n(43),_=(n(27),n(10),n(13),n(20)),m=n(262),h=(n(9),n(308)),p=(n(2),{Mixin:{_reconcilerInstantiateChildren:function(e,t,n){return m.instantiateChildren(e,t,n)},_reconcilerUpdateChildren:function(e,t,n,r,a,i){var o,s=0;return o=h(t,s),m.updateChildren(e,o,n,r,a,this,this._hostContainerInfo,i,s),o},mountChildren:function(e,t,n){var r=this._reconcilerInstantiateChildren(e,t,n);this._renderedChildren=r;var a=[],i=0;for(var o in r)if(r.hasOwnProperty(o)){var s=r[o],u=0,d=_.mountComponent(s,t,this,this._hostContainerInfo,n,u);s._mountIndex=i++,a.push(d)}return a},updateTextContent:function(e){var t=this._renderedChildren;m.unmountChildren(t,!1);for(var n in t)t.hasOwnProperty(n)&&l("118");var r=[s(e)];d(this,r)},updateMarkup:function(e){var t=this._renderedChildren;m.unmountChildren(t,!1);for(var n in t)t.hasOwnProperty(n)&&l("118");var r=[o(e)];d(this,r)},updateChildren:function(e,t,n){this._updateChildren(e,t,n)},_updateChildren:function(e,t,n){var r=this._renderedChildren,a={},i=[],o=this._reconcilerUpdateChildren(r,e,i,a,t,n);if(o||r){var s,l=null,c=0,m=0,h=0,p=null;for(s in o)if(o.hasOwnProperty(s)){var f=r&&r[s],y=o[s];f===y?(l=u(l,this.moveChild(f,p,c,m)),m=Math.max(f._mountIndex,m),f._mountIndex=c):(f&&(m=Math.max(f._mountIndex,m)),l=u(l,this._mountChildAtIndex(y,i[h],p,c,t,n)),h++),c++,p=_.getHostNode(y)}for(s in a)a.hasOwnProperty(s)&&(l=u(l,this._unmountChild(r[s],a[s])));l&&d(this,l),this._renderedChildren=o}},unmountChildren:function(e){var t=this._renderedChildren;m.unmountChildren(t,e),this._renderedChildren=null},moveChild:function(e,t,n,r){if(e._mountIndex=t)return{node:a,offset:t-i};i=o}a=n(r(a))}}e.exports=a},function(e,t,n){"use strict";function r(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n["ms"+e]="MS"+t,n["O"+e]="o"+t.toLowerCase(),n}function a(e){if(s[e])return s[e];if(!o[e])return e;var t=o[e];for(var n in t)if(t.hasOwnProperty(n)&&n in u)return s[e]=t[n];return""}var i=n(7),o={animationend:r("Animation","AnimationEnd"),animationiteration:r("Animation","AnimationIteration"),animationstart:r("Animation","AnimationStart"),transitionend:r("Transition","TransitionEnd")},s={},u={};i.canUseDOM&&(u=document.createElement("div").style,"AnimationEvent"in window||(delete o.animationend.animation,delete o.animationiteration.animation,delete o.animationstart.animation),"TransitionEvent"in window||delete o.transitionend.transition),e.exports=a},function(e,t,n){"use strict";function r(e){return'"'+a(e)+'"'}var a=n(32);e.exports=r},function(e,t,n){"use strict";var r=n(181);e.exports=r.renderSubtreeIntoContainer},41,[337,23],function(e,t,n){"use strict";function r(e){return(""+e).replace(g,"$&/")}function a(e,t){this.func=e,this.context=t,this.count=0}function i(e,t,n){var r=e.func,a=e.context;r.call(a,t,e.count++)}function o(e,t,n){if(null==e)return e;var r=a.getPooled(t,n);y(e,i,r),a.release(r)}function s(e,t,n,r){this.result=e,this.keyPrefix=t,this.func=n,this.context=r,this.count=0}function u(e,t,n){var a=e.result,i=e.keyPrefix,o=e.func,s=e.context,u=o.call(s,t,e.count++);Array.isArray(u)?d(u,a,n,f.thatReturnsArgument):null!=u&&(p.isValidElement(u)&&(u=p.cloneAndReplaceKey(u,i+(!u.key||t&&t.key===u.key?"":r(u.key)+"/")+n)),a.push(u))}function d(e,t,n,a,i){var o="";null!=n&&(o=r(n)+"/");var d=s.getPooled(t,o,a,i);y(e,u,d),s.release(d)}function l(e,t,n){if(null==e)return e;var r=[];return d(e,r,null,t,n),r}function c(e,t,n){return null}function _(e,t){return y(e,c,null)}function m(e){var t=[];return d(e,t,null,f.thatReturnsArgument),t}var h=n(317),p=n(22),f=n(9),y=n(326),M=h.twoArgumentPooler,v=h.fourArgumentPooler,g=/\/+/g;a.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},h.addPoolingTo(a,M),s.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},h.addPoolingTo(s,v);var L={forEach:o,map:l,mapIntoWithKeyPrefixInternal:d,count:_,toArray:m};e.exports=L},function(e,t,n){"use strict";function r(e){return e}function a(e,t){var n=g.hasOwnProperty(t)?g[t]:null;Y.hasOwnProperty(t)&&("OVERRIDE_BASE"!==n?_("73",t):void 0),e&&("DEFINE_MANY"!==n&&"DEFINE_MANY_MERGED"!==n?_("74",t):void 0)}function i(e,t){if(t){"function"==typeof t?_("75"):void 0,p.isValidElement(t)?_("76"):void 0;var n=e.prototype,r=n.__reactAutoBindPairs;t.hasOwnProperty(M)&&L.mixins(e,t.mixins);for(var i in t)if(t.hasOwnProperty(i)&&i!==M){var o=t[i],s=n.hasOwnProperty(i);if(a(s,i),L.hasOwnProperty(i))L[i](e,o);else{var l=g.hasOwnProperty(i),c="function"==typeof o,m=c&&!l&&!s&&t.autobind!==!1;if(m)r.push(i,o),n[i]=o;else if(s){var h=g[i];!l||"DEFINE_MANY_MERGED"!==h&&"DEFINE_MANY"!==h?_("77",h,i):void 0,"DEFINE_MANY_MERGED"===h?n[i]=u(n[i],o):"DEFINE_MANY"===h&&(n[i]=d(n[i],o))}else n[i]=o}}}else;}function o(e,t){if(t)for(var n in t){var r=t[n];if(t.hasOwnProperty(n)){var a=n in L;a?_("78",n):void 0;var i=n in e;i?_("79",n):void 0,e[n]=r}}}function s(e,t){e&&t&&"object"==typeof e&&"object"==typeof t?void 0:_("80");for(var n in t)t.hasOwnProperty(n)&&(void 0!==e[n]?_("81",n):void 0,e[n]=t[n]);return e}function u(e,t){return function(){var n=e.apply(this,arguments),r=t.apply(this,arguments);if(null==n)return r;if(null==r)return n;var a={};return s(a,n),s(a,r),a}}function d(e,t){return function(){e.apply(this,arguments),t.apply(this,arguments)}}function l(e,t){var n=t.bind(e);return n}function c(e){for(var t=e.__reactAutoBindPairs,n=0;n>"),T={array:o("array"),bool:o("boolean"),func:o("function"),number:o("number"),object:o("object"),string:o("string"),symbol:o("symbol"),any:s(),arrayOf:u,element:d(),instanceOf:l,node:h(),objectOf:_,oneOf:c,oneOfType:m,shape:p};a.prototype=Error.prototype,e.exports=T},286,function(e,t,n){"use strict";function r(e,t,n){this.props=e,this.context=t,this.refs=u,this.updater=n||s}function a(){}var i=n(5),o=n(53),s=n(54),u=n(24);a.prototype=o.prototype,r.prototype=new a,r.prototype.constructor=r,i(r.prototype,o.prototype),r.prototype.isPureReactComponent=!0,e.exports=r},291,function(e,t,n){"use strict";function r(e){return i.isValidElement(e)?void 0:a("143"),e}var a=n(23),i=n(22);n(2);e.exports=r},function(e,t,n){"use strict";function r(e,t){return e&&"object"==typeof e&&null!=e.key?d.escape(e.key):t.toString(36)}function a(e,t,n,i){var _=typeof e;if("undefined"!==_&&"boolean"!==_||(e=null),null===e||"string"===_||"number"===_||"object"===_&&e.$$typeof===s)return n(i,e,""===t?l+r(e,0):t),1;var m,h,p=0,f=""===t?l:t+c;if(Array.isArray(e))for(var y=0;y-1?t:e}function c(e,t){t=t||{};var n=t.body;if(c.prototype.isPrototypeOf(e)){if(e.bodyUsed)throw new TypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=new a(e.headers)),this.method=e.method,this.mode=e.mode,n||(n=e._bodyInit,e.bodyUsed=!0)}else this.url=e;if(this.credentials=t.credentials||this.credentials||"omit",!t.headers&&this.headers||(this.headers=new a(t.headers)),this.method=l(t.method||this.method||"GET"),this.mode=t.mode||this.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&n)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(n)}function _(e){var t=new FormData;return e.trim().split("&").forEach(function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),a=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(a))}}),t}function m(e){var t=new a,n=(e.getAllResponseHeaders()||"").trim().split("\n");return n.forEach(function(e){var n=e.trim().split(":"),r=n.shift().trim(),a=n.join(":").trim();t.append(r,a)}),t}function h(e,t){t||(t={}),this.type="default",this.status=t.status,this.ok=this.status>=200&&this.status<300,this.statusText=t.statusText,this.headers=t.headers instanceof a?t.headers:new a(t.headers),this.url=t.url||"",this._initBody(e)}if(!e.fetch){var p={searchParams:"URLSearchParams"in e,iterable:"Symbol"in e&&"iterator"in Symbol,blob:"FileReader"in e&&"Blob"in e&&function(){try{return new Blob,!0}catch(e){return!1}}(),formData:"FormData"in e,arrayBuffer:"ArrayBuffer"in e};a.prototype.append=function(e,r){e=t(e),r=n(r);var a=this.map[e];a||(a=[],this.map[e]=a),a.push(r)},a.prototype.delete=function(e){delete this.map[t(e)]},a.prototype.get=function(e){var n=this.map[t(e)];return n?n[0]:null},a.prototype.getAll=function(e){return this.map[t(e)]||[]},a.prototype.has=function(e){return this.map.hasOwnProperty(t(e))},a.prototype.set=function(e,r){this.map[t(e)]=[n(r)]},a.prototype.forEach=function(e,t){Object.getOwnPropertyNames(this.map).forEach(function(n){this.map[n].forEach(function(r){e.call(t,r,n,this)},this)},this)},a.prototype.keys=function(){var e=[];return this.forEach(function(t,n){e.push(n)}),r(e)},a.prototype.values=function(){var e=[];return this.forEach(function(t){e.push(t)}),r(e)},a.prototype.entries=function(){var e=[];return this.forEach(function(t,n){e.push([n,t])}),r(e)},p.iterable&&(a.prototype[Symbol.iterator]=a.prototype.entries);var f=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];c.prototype.clone=function(){return new c(this)},d.call(c.prototype),d.call(h.prototype),h.prototype.clone=function(){return new h(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new a(this.headers),url:this.url})},h.error=function(){var e=new h(null,{status:0,statusText:""});return e.type="error",e};var y=[301,302,303,307,308];h.redirect=function(e,t){if(y.indexOf(t)===-1)throw new RangeError("Invalid status code");return new h(null,{status:t,headers:{location:e}})},e.Headers=a,e.Request=c,e.Response=h,e.fetch=function(e,t){return new Promise(function(n,r){function a(){return"responseURL"in o?o.responseURL:/^X-Request-URL:/m.test(o.getAllResponseHeaders())?o.getResponseHeader("X-Request-URL"):void 0}var i;i=c.prototype.isPrototypeOf(e)&&!t?e:new c(e,t);var o=new XMLHttpRequest;o.onload=function(){var e={status:o.status,statusText:o.statusText,headers:m(o),url:a()},t="response"in o?o.response:o.responseText;n(new h(t,e))},o.onerror=function(){r(new TypeError("Network request failed"))},o.ontimeout=function(){r(new TypeError("Network request failed"))},o.open(i.method,i.url,!0),"include"===i.credentials&&(o.withCredentials=!0),"responseType"in o&&p.blob&&(o.responseType="blob"),i.headers.forEach(function(e,t){o.setRequestHeader(t,e)}),o.send("undefined"==typeof i._bodyInit?null:i._bodyInit)})},e.fetch.polyfill=!0}}("undefined"!=typeof self?self:this)},function(e,t,n,r){"use strict";var a=n(r),i=(n(2),function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)}),o=function(e,t){var n=this;if(n.instancePool.length){var r=n.instancePool.pop();return n.call(r,e,t),r}return new n(e,t)},s=function(e,t,n){var r=this;if(r.instancePool.length){var a=r.instancePool.pop();return r.call(a,e,t,n),a}return new r(e,t,n)},u=function(e,t,n,r){var a=this;if(a.instancePool.length){var i=a.instancePool.pop();return a.call(i,e,t,n,r),i}return new a(e,t,n,r)},d=function(e,t,n,r,a){var i=this;if(i.instancePool.length){var o=i.instancePool.pop();return i.call(o,e,t,n,r,a),o}return new i(e,t,n,r,a)},l=function(e){var t=this;e instanceof t?void 0:a("25"),e.destructor(),t.instancePool.length>> 0;\n\t\n\t for (var i = 0; i < len; i++) {\n\t if (i in t && fun.call(this, t[i], i, t)) {\n\t return true;\n\t }\n\t }\n\t\n\t return false;\n\t };\n\t}\n\t\n\tvar some$1 = some;\n\t\n\tfunction isValid(m) {\n\t if (m._isValid == null) {\n\t var flags = getParsingFlags(m);\n\t var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n\t return i != null;\n\t });\n\t var isNowValid = !isNaN(m._d.getTime()) &&\n\t flags.overflow < 0 &&\n\t !flags.empty &&\n\t !flags.invalidMonth &&\n\t !flags.invalidWeekday &&\n\t !flags.nullInput &&\n\t !flags.invalidFormat &&\n\t !flags.userInvalidated &&\n\t (!flags.meridiem || (flags.meridiem && parsedParts));\n\t\n\t if (m._strict) {\n\t isNowValid = isNowValid &&\n\t flags.charsLeftOver === 0 &&\n\t flags.unusedTokens.length === 0 &&\n\t flags.bigHour === undefined;\n\t }\n\t\n\t if (Object.isFrozen == null || !Object.isFrozen(m)) {\n\t m._isValid = isNowValid;\n\t }\n\t else {\n\t return isNowValid;\n\t }\n\t }\n\t return m._isValid;\n\t}\n\t\n\tfunction createInvalid (flags) {\n\t var m = createUTC(NaN);\n\t if (flags != null) {\n\t extend(getParsingFlags(m), flags);\n\t }\n\t else {\n\t getParsingFlags(m).userInvalidated = true;\n\t }\n\t\n\t return m;\n\t}\n\t\n\tfunction isUndefined(input) {\n\t return input === void 0;\n\t}\n\t\n\t// Plugins that add properties should also add the key here (null value),\n\t// so we can properly clone ourselves.\n\tvar momentProperties = hooks.momentProperties = [];\n\t\n\tfunction copyConfig(to, from) {\n\t var i, prop, val;\n\t\n\t if (!isUndefined(from._isAMomentObject)) {\n\t to._isAMomentObject = from._isAMomentObject;\n\t }\n\t if (!isUndefined(from._i)) {\n\t to._i = from._i;\n\t }\n\t if (!isUndefined(from._f)) {\n\t to._f = from._f;\n\t }\n\t if (!isUndefined(from._l)) {\n\t to._l = from._l;\n\t }\n\t if (!isUndefined(from._strict)) {\n\t to._strict = from._strict;\n\t }\n\t if (!isUndefined(from._tzm)) {\n\t to._tzm = from._tzm;\n\t }\n\t if (!isUndefined(from._isUTC)) {\n\t to._isUTC = from._isUTC;\n\t }\n\t if (!isUndefined(from._offset)) {\n\t to._offset = from._offset;\n\t }\n\t if (!isUndefined(from._pf)) {\n\t to._pf = getParsingFlags(from);\n\t }\n\t if (!isUndefined(from._locale)) {\n\t to._locale = from._locale;\n\t }\n\t\n\t if (momentProperties.length > 0) {\n\t for (i in momentProperties) {\n\t prop = momentProperties[i];\n\t val = from[prop];\n\t if (!isUndefined(val)) {\n\t to[prop] = val;\n\t }\n\t }\n\t }\n\t\n\t return to;\n\t}\n\t\n\tvar updateInProgress = false;\n\t\n\t// Moment prototype object\n\tfunction Moment(config) {\n\t copyConfig(this, config);\n\t this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n\t if (!this.isValid()) {\n\t this._d = new Date(NaN);\n\t }\n\t // Prevent infinite loop in case updateOffset creates new moment\n\t // objects.\n\t if (updateInProgress === false) {\n\t updateInProgress = true;\n\t hooks.updateOffset(this);\n\t updateInProgress = false;\n\t }\n\t}\n\t\n\tfunction isMoment (obj) {\n\t return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n\t}\n\t\n\tfunction absFloor (number) {\n\t if (number < 0) {\n\t // -0 -> 0\n\t return Math.ceil(number) || 0;\n\t } else {\n\t return Math.floor(number);\n\t }\n\t}\n\t\n\tfunction toInt(argumentForCoercion) {\n\t var coercedNumber = +argumentForCoercion,\n\t value = 0;\n\t\n\t if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n\t value = absFloor(coercedNumber);\n\t }\n\t\n\t return value;\n\t}\n\t\n\t// compare two arrays, return the number of differences\n\tfunction compareArrays(array1, array2, dontConvert) {\n\t var len = Math.min(array1.length, array2.length),\n\t lengthDiff = Math.abs(array1.length - array2.length),\n\t diffs = 0,\n\t i;\n\t for (i = 0; i < len; i++) {\n\t if ((dontConvert && array1[i] !== array2[i]) ||\n\t (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n\t diffs++;\n\t }\n\t }\n\t return diffs + lengthDiff;\n\t}\n\t\n\tfunction warn(msg) {\n\t if (hooks.suppressDeprecationWarnings === false &&\n\t (typeof console !== 'undefined') && console.warn) {\n\t console.warn('Deprecation warning: ' + msg);\n\t }\n\t}\n\t\n\tfunction deprecate(msg, fn) {\n\t var firstTime = true;\n\t\n\t return extend(function () {\n\t if (hooks.deprecationHandler != null) {\n\t hooks.deprecationHandler(null, msg);\n\t }\n\t if (firstTime) {\n\t var args = [];\n\t var arg;\n\t for (var i = 0; i < arguments.length; i++) {\n\t arg = '';\n\t if (typeof arguments[i] === 'object') {\n\t arg += '\\n[' + i + '] ';\n\t for (var key in arguments[0]) {\n\t arg += key + ': ' + arguments[0][key] + ', ';\n\t }\n\t arg = arg.slice(0, -2); // Remove trailing comma and space\n\t } else {\n\t arg = arguments[i];\n\t }\n\t args.push(arg);\n\t }\n\t warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n\t firstTime = false;\n\t }\n\t return fn.apply(this, arguments);\n\t }, fn);\n\t}\n\t\n\tvar deprecations = {};\n\t\n\tfunction deprecateSimple(name, msg) {\n\t if (hooks.deprecationHandler != null) {\n\t hooks.deprecationHandler(name, msg);\n\t }\n\t if (!deprecations[name]) {\n\t warn(msg);\n\t deprecations[name] = true;\n\t }\n\t}\n\t\n\thooks.suppressDeprecationWarnings = false;\n\thooks.deprecationHandler = null;\n\t\n\tfunction isFunction(input) {\n\t return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n\t}\n\t\n\tfunction set (config) {\n\t var prop, i;\n\t for (i in config) {\n\t prop = config[i];\n\t if (isFunction(prop)) {\n\t this[i] = prop;\n\t } else {\n\t this['_' + i] = prop;\n\t }\n\t }\n\t this._config = config;\n\t // Lenient ordinal parsing accepts just a number in addition to\n\t // number + (possibly) stuff coming from _ordinalParseLenient.\n\t this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\\d{1,2}/).source);\n\t}\n\t\n\tfunction mergeConfigs(parentConfig, childConfig) {\n\t var res = extend({}, parentConfig), prop;\n\t for (prop in childConfig) {\n\t if (hasOwnProp(childConfig, prop)) {\n\t if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n\t res[prop] = {};\n\t extend(res[prop], parentConfig[prop]);\n\t extend(res[prop], childConfig[prop]);\n\t } else if (childConfig[prop] != null) {\n\t res[prop] = childConfig[prop];\n\t } else {\n\t delete res[prop];\n\t }\n\t }\n\t }\n\t for (prop in parentConfig) {\n\t if (hasOwnProp(parentConfig, prop) &&\n\t !hasOwnProp(childConfig, prop) &&\n\t isObject(parentConfig[prop])) {\n\t // make sure changes to properties don't modify parent config\n\t res[prop] = extend({}, res[prop]);\n\t }\n\t }\n\t return res;\n\t}\n\t\n\tfunction Locale(config) {\n\t if (config != null) {\n\t this.set(config);\n\t }\n\t}\n\t\n\tvar keys;\n\t\n\tif (Object.keys) {\n\t keys = Object.keys;\n\t} else {\n\t keys = function (obj) {\n\t var i, res = [];\n\t for (i in obj) {\n\t if (hasOwnProp(obj, i)) {\n\t res.push(i);\n\t }\n\t }\n\t return res;\n\t };\n\t}\n\t\n\tvar keys$1 = keys;\n\t\n\tvar defaultCalendar = {\n\t sameDay : '[Today at] LT',\n\t nextDay : '[Tomorrow at] LT',\n\t nextWeek : 'dddd [at] LT',\n\t lastDay : '[Yesterday at] LT',\n\t lastWeek : '[Last] dddd [at] LT',\n\t sameElse : 'L'\n\t};\n\t\n\tfunction calendar (key, mom, now) {\n\t var output = this._calendar[key] || this._calendar['sameElse'];\n\t return isFunction(output) ? output.call(mom, now) : output;\n\t}\n\t\n\tvar defaultLongDateFormat = {\n\t LTS : 'h:mm:ss A',\n\t LT : 'h:mm A',\n\t L : 'MM/DD/YYYY',\n\t LL : 'MMMM D, YYYY',\n\t LLL : 'MMMM D, YYYY h:mm A',\n\t LLLL : 'dddd, MMMM D, YYYY h:mm A'\n\t};\n\t\n\tfunction longDateFormat (key) {\n\t var format = this._longDateFormat[key],\n\t formatUpper = this._longDateFormat[key.toUpperCase()];\n\t\n\t if (format || !formatUpper) {\n\t return format;\n\t }\n\t\n\t this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n\t return val.slice(1);\n\t });\n\t\n\t return this._longDateFormat[key];\n\t}\n\t\n\tvar defaultInvalidDate = 'Invalid date';\n\t\n\tfunction invalidDate () {\n\t return this._invalidDate;\n\t}\n\t\n\tvar defaultOrdinal = '%d';\n\tvar defaultOrdinalParse = /\\d{1,2}/;\n\t\n\tfunction ordinal (number) {\n\t return this._ordinal.replace('%d', number);\n\t}\n\t\n\tvar defaultRelativeTime = {\n\t future : 'in %s',\n\t past : '%s ago',\n\t s : 'a few seconds',\n\t m : 'a minute',\n\t mm : '%d minutes',\n\t h : 'an hour',\n\t hh : '%d hours',\n\t d : 'a day',\n\t dd : '%d days',\n\t M : 'a month',\n\t MM : '%d months',\n\t y : 'a year',\n\t yy : '%d years'\n\t};\n\t\n\tfunction relativeTime (number, withoutSuffix, string, isFuture) {\n\t var output = this._relativeTime[string];\n\t return (isFunction(output)) ?\n\t output(number, withoutSuffix, string, isFuture) :\n\t output.replace(/%d/i, number);\n\t}\n\t\n\tfunction pastFuture (diff, output) {\n\t var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n\t return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n\t}\n\t\n\tvar aliases = {};\n\t\n\tfunction addUnitAlias (unit, shorthand) {\n\t var lowerCase = unit.toLowerCase();\n\t aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n\t}\n\t\n\tfunction normalizeUnits(units) {\n\t return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n\t}\n\t\n\tfunction normalizeObjectUnits(inputObject) {\n\t var normalizedInput = {},\n\t normalizedProp,\n\t prop;\n\t\n\t for (prop in inputObject) {\n\t if (hasOwnProp(inputObject, prop)) {\n\t normalizedProp = normalizeUnits(prop);\n\t if (normalizedProp) {\n\t normalizedInput[normalizedProp] = inputObject[prop];\n\t }\n\t }\n\t }\n\t\n\t return normalizedInput;\n\t}\n\t\n\tvar priorities = {};\n\t\n\tfunction addUnitPriority(unit, priority) {\n\t priorities[unit] = priority;\n\t}\n\t\n\tfunction getPrioritizedUnits(unitsObj) {\n\t var units = [];\n\t for (var u in unitsObj) {\n\t units.push({unit: u, priority: priorities[u]});\n\t }\n\t units.sort(function (a, b) {\n\t return a.priority - b.priority;\n\t });\n\t return units;\n\t}\n\t\n\tfunction makeGetSet (unit, keepTime) {\n\t return function (value) {\n\t if (value != null) {\n\t set$1(this, unit, value);\n\t hooks.updateOffset(this, keepTime);\n\t return this;\n\t } else {\n\t return get(this, unit);\n\t }\n\t };\n\t}\n\t\n\tfunction get (mom, unit) {\n\t return mom.isValid() ?\n\t mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n\t}\n\t\n\tfunction set$1 (mom, unit, value) {\n\t if (mom.isValid()) {\n\t mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n\t }\n\t}\n\t\n\t// MOMENTS\n\t\n\tfunction stringGet (units) {\n\t units = normalizeUnits(units);\n\t if (isFunction(this[units])) {\n\t return this[units]();\n\t }\n\t return this;\n\t}\n\t\n\t\n\tfunction stringSet (units, value) {\n\t if (typeof units === 'object') {\n\t units = normalizeObjectUnits(units);\n\t var prioritized = getPrioritizedUnits(units);\n\t for (var i = 0; i < prioritized.length; i++) {\n\t this[prioritized[i].unit](units[prioritized[i].unit]);\n\t }\n\t } else {\n\t units = normalizeUnits(units);\n\t if (isFunction(this[units])) {\n\t return this[units](value);\n\t }\n\t }\n\t return this;\n\t}\n\t\n\tfunction zeroFill(number, targetLength, forceSign) {\n\t var absNumber = '' + Math.abs(number),\n\t zerosToFill = targetLength - absNumber.length,\n\t sign = number >= 0;\n\t return (sign ? (forceSign ? '+' : '') : '-') +\n\t Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n\t}\n\t\n\tvar 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;\n\t\n\tvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\t\n\tvar formatFunctions = {};\n\t\n\tvar formatTokenFunctions = {};\n\t\n\t// token: 'M'\n\t// padded: ['MM', 2]\n\t// ordinal: 'Mo'\n\t// callback: function () { this.month() + 1 }\n\tfunction addFormatToken (token, padded, ordinal, callback) {\n\t var func = callback;\n\t if (typeof callback === 'string') {\n\t func = function () {\n\t return this[callback]();\n\t };\n\t }\n\t if (token) {\n\t formatTokenFunctions[token] = func;\n\t }\n\t if (padded) {\n\t formatTokenFunctions[padded[0]] = function () {\n\t return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n\t };\n\t }\n\t if (ordinal) {\n\t formatTokenFunctions[ordinal] = function () {\n\t return this.localeData().ordinal(func.apply(this, arguments), token);\n\t };\n\t }\n\t}\n\t\n\tfunction removeFormattingTokens(input) {\n\t if (input.match(/\\[[\\s\\S]/)) {\n\t return input.replace(/^\\[|\\]$/g, '');\n\t }\n\t return input.replace(/\\\\/g, '');\n\t}\n\t\n\tfunction makeFormatFunction(format) {\n\t var array = format.match(formattingTokens), i, length;\n\t\n\t for (i = 0, length = array.length; i < length; i++) {\n\t if (formatTokenFunctions[array[i]]) {\n\t array[i] = formatTokenFunctions[array[i]];\n\t } else {\n\t array[i] = removeFormattingTokens(array[i]);\n\t }\n\t }\n\t\n\t return function (mom) {\n\t var output = '', i;\n\t for (i = 0; i < length; i++) {\n\t output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n\t }\n\t return output;\n\t };\n\t}\n\t\n\t// format date using native date object\n\tfunction formatMoment(m, format) {\n\t if (!m.isValid()) {\n\t return m.localeData().invalidDate();\n\t }\n\t\n\t format = expandFormat(format, m.localeData());\n\t formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\t\n\t return formatFunctions[format](m);\n\t}\n\t\n\tfunction expandFormat(format, locale) {\n\t var i = 5;\n\t\n\t function replaceLongDateFormatTokens(input) {\n\t return locale.longDateFormat(input) || input;\n\t }\n\t\n\t localFormattingTokens.lastIndex = 0;\n\t while (i >= 0 && localFormattingTokens.test(format)) {\n\t format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n\t localFormattingTokens.lastIndex = 0;\n\t i -= 1;\n\t }\n\t\n\t return format;\n\t}\n\t\n\tvar match1 = /\\d/; // 0 - 9\n\tvar match2 = /\\d\\d/; // 00 - 99\n\tvar match3 = /\\d{3}/; // 000 - 999\n\tvar match4 = /\\d{4}/; // 0000 - 9999\n\tvar match6 = /[+-]?\\d{6}/; // -999999 - 999999\n\tvar match1to2 = /\\d\\d?/; // 0 - 99\n\tvar match3to4 = /\\d\\d\\d\\d?/; // 999 - 9999\n\tvar match5to6 = /\\d\\d\\d\\d\\d\\d?/; // 99999 - 999999\n\tvar match1to3 = /\\d{1,3}/; // 0 - 999\n\tvar match1to4 = /\\d{1,4}/; // 0 - 9999\n\tvar match1to6 = /[+-]?\\d{1,6}/; // -999999 - 999999\n\t\n\tvar matchUnsigned = /\\d+/; // 0 - inf\n\tvar matchSigned = /[+-]?\\d+/; // -inf - inf\n\t\n\tvar matchOffset = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n\tvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\t\n\tvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\t\n\t// any word (or two) characters or numbers including two/three word month in arabic.\n\t// includes scottish gaelic two word and hyphenated months\n\tvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\t\n\t\n\tvar regexes = {};\n\t\n\tfunction addRegexToken (token, regex, strictRegex) {\n\t regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n\t return (isStrict && strictRegex) ? strictRegex : regex;\n\t };\n\t}\n\t\n\tfunction getParseRegexForToken (token, config) {\n\t if (!hasOwnProp(regexes, token)) {\n\t return new RegExp(unescapeFormat(token));\n\t }\n\t\n\t return regexes[token](config._strict, config._locale);\n\t}\n\t\n\t// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n\tfunction unescapeFormat(s) {\n\t return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n\t return p1 || p2 || p3 || p4;\n\t }));\n\t}\n\t\n\tfunction regexEscape(s) {\n\t return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t}\n\t\n\tvar tokens = {};\n\t\n\tfunction addParseToken (token, callback) {\n\t var i, func = callback;\n\t if (typeof token === 'string') {\n\t token = [token];\n\t }\n\t if (isNumber(callback)) {\n\t func = function (input, array) {\n\t array[callback] = toInt(input);\n\t };\n\t }\n\t for (i = 0; i < token.length; i++) {\n\t tokens[token[i]] = func;\n\t }\n\t}\n\t\n\tfunction addWeekParseToken (token, callback) {\n\t addParseToken(token, function (input, array, config, token) {\n\t config._w = config._w || {};\n\t callback(input, config._w, config, token);\n\t });\n\t}\n\t\n\tfunction addTimeToArrayFromToken(token, input, config) {\n\t if (input != null && hasOwnProp(tokens, token)) {\n\t tokens[token](input, config._a, config, token);\n\t }\n\t}\n\t\n\tvar YEAR = 0;\n\tvar MONTH = 1;\n\tvar DATE = 2;\n\tvar HOUR = 3;\n\tvar MINUTE = 4;\n\tvar SECOND = 5;\n\tvar MILLISECOND = 6;\n\tvar WEEK = 7;\n\tvar WEEKDAY = 8;\n\t\n\tvar indexOf;\n\t\n\tif (Array.prototype.indexOf) {\n\t indexOf = Array.prototype.indexOf;\n\t} else {\n\t indexOf = function (o) {\n\t // I know\n\t var i;\n\t for (i = 0; i < this.length; ++i) {\n\t if (this[i] === o) {\n\t return i;\n\t }\n\t }\n\t return -1;\n\t };\n\t}\n\t\n\tvar indexOf$1 = indexOf;\n\t\n\tfunction daysInMonth(year, month) {\n\t return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('M', ['MM', 2], 'Mo', function () {\n\t return this.month() + 1;\n\t});\n\t\n\taddFormatToken('MMM', 0, 0, function (format) {\n\t return this.localeData().monthsShort(this, format);\n\t});\n\t\n\taddFormatToken('MMMM', 0, 0, function (format) {\n\t return this.localeData().months(this, format);\n\t});\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('month', 'M');\n\t\n\t// PRIORITY\n\t\n\taddUnitPriority('month', 8);\n\t\n\t// PARSING\n\t\n\taddRegexToken('M', match1to2);\n\taddRegexToken('MM', match1to2, match2);\n\taddRegexToken('MMM', function (isStrict, locale) {\n\t return locale.monthsShortRegex(isStrict);\n\t});\n\taddRegexToken('MMMM', function (isStrict, locale) {\n\t return locale.monthsRegex(isStrict);\n\t});\n\t\n\taddParseToken(['M', 'MM'], function (input, array) {\n\t array[MONTH] = toInt(input) - 1;\n\t});\n\t\n\taddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n\t var month = config._locale.monthsParse(input, token, config._strict);\n\t // if we didn't find a month name, mark the date as invalid.\n\t if (month != null) {\n\t array[MONTH] = month;\n\t } else {\n\t getParsingFlags(config).invalidMonth = input;\n\t }\n\t});\n\t\n\t// LOCALES\n\t\n\tvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\n\tvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n\tfunction localeMonths (m, format) {\n\t if (!m) {\n\t return this._months;\n\t }\n\t return isArray(this._months) ? this._months[m.month()] :\n\t this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n\t}\n\t\n\tvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n\tfunction localeMonthsShort (m, format) {\n\t if (!m) {\n\t return this._monthsShort;\n\t }\n\t return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n\t this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n\t}\n\t\n\tfunction handleStrictParse(monthName, format, strict) {\n\t var i, ii, mom, llc = monthName.toLocaleLowerCase();\n\t if (!this._monthsParse) {\n\t // this is not used\n\t this._monthsParse = [];\n\t this._longMonthsParse = [];\n\t this._shortMonthsParse = [];\n\t for (i = 0; i < 12; ++i) {\n\t mom = createUTC([2000, i]);\n\t this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n\t this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n\t }\n\t }\n\t\n\t if (strict) {\n\t if (format === 'MMM') {\n\t ii = indexOf$1.call(this._shortMonthsParse, llc);\n\t return ii !== -1 ? ii : null;\n\t } else {\n\t ii = indexOf$1.call(this._longMonthsParse, llc);\n\t return ii !== -1 ? ii : null;\n\t }\n\t } else {\n\t if (format === 'MMM') {\n\t ii = indexOf$1.call(this._shortMonthsParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._longMonthsParse, llc);\n\t return ii !== -1 ? ii : null;\n\t } else {\n\t ii = indexOf$1.call(this._longMonthsParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._shortMonthsParse, llc);\n\t return ii !== -1 ? ii : null;\n\t }\n\t }\n\t}\n\t\n\tfunction localeMonthsParse (monthName, format, strict) {\n\t var i, mom, regex;\n\t\n\t if (this._monthsParseExact) {\n\t return handleStrictParse.call(this, monthName, format, strict);\n\t }\n\t\n\t if (!this._monthsParse) {\n\t this._monthsParse = [];\n\t this._longMonthsParse = [];\n\t this._shortMonthsParse = [];\n\t }\n\t\n\t // TODO: add sorting\n\t // Sorting makes sure if one month (or abbr) is a prefix of another\n\t // see sorting in computeMonthsParse\n\t for (i = 0; i < 12; i++) {\n\t // make the regex if we don't have it already\n\t mom = createUTC([2000, i]);\n\t if (strict && !this._longMonthsParse[i]) {\n\t this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n\t this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n\t }\n\t if (!strict && !this._monthsParse[i]) {\n\t regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n\t this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n\t }\n\t // test the regex\n\t if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n\t return i;\n\t } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n\t return i;\n\t } else if (!strict && this._monthsParse[i].test(monthName)) {\n\t return i;\n\t }\n\t }\n\t}\n\t\n\t// MOMENTS\n\t\n\tfunction setMonth (mom, value) {\n\t var dayOfMonth;\n\t\n\t if (!mom.isValid()) {\n\t // No op\n\t return mom;\n\t }\n\t\n\t if (typeof value === 'string') {\n\t if (/^\\d+$/.test(value)) {\n\t value = toInt(value);\n\t } else {\n\t value = mom.localeData().monthsParse(value);\n\t // TODO: Another silent failure?\n\t if (!isNumber(value)) {\n\t return mom;\n\t }\n\t }\n\t }\n\t\n\t dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n\t mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n\t return mom;\n\t}\n\t\n\tfunction getSetMonth (value) {\n\t if (value != null) {\n\t setMonth(this, value);\n\t hooks.updateOffset(this, true);\n\t return this;\n\t } else {\n\t return get(this, 'Month');\n\t }\n\t}\n\t\n\tfunction getDaysInMonth () {\n\t return daysInMonth(this.year(), this.month());\n\t}\n\t\n\tvar defaultMonthsShortRegex = matchWord;\n\tfunction monthsShortRegex (isStrict) {\n\t if (this._monthsParseExact) {\n\t if (!hasOwnProp(this, '_monthsRegex')) {\n\t computeMonthsParse.call(this);\n\t }\n\t if (isStrict) {\n\t return this._monthsShortStrictRegex;\n\t } else {\n\t return this._monthsShortRegex;\n\t }\n\t } else {\n\t if (!hasOwnProp(this, '_monthsShortRegex')) {\n\t this._monthsShortRegex = defaultMonthsShortRegex;\n\t }\n\t return this._monthsShortStrictRegex && isStrict ?\n\t this._monthsShortStrictRegex : this._monthsShortRegex;\n\t }\n\t}\n\t\n\tvar defaultMonthsRegex = matchWord;\n\tfunction monthsRegex (isStrict) {\n\t if (this._monthsParseExact) {\n\t if (!hasOwnProp(this, '_monthsRegex')) {\n\t computeMonthsParse.call(this);\n\t }\n\t if (isStrict) {\n\t return this._monthsStrictRegex;\n\t } else {\n\t return this._monthsRegex;\n\t }\n\t } else {\n\t if (!hasOwnProp(this, '_monthsRegex')) {\n\t this._monthsRegex = defaultMonthsRegex;\n\t }\n\t return this._monthsStrictRegex && isStrict ?\n\t this._monthsStrictRegex : this._monthsRegex;\n\t }\n\t}\n\t\n\tfunction computeMonthsParse () {\n\t function cmpLenRev(a, b) {\n\t return b.length - a.length;\n\t }\n\t\n\t var shortPieces = [], longPieces = [], mixedPieces = [],\n\t i, mom;\n\t for (i = 0; i < 12; i++) {\n\t // make the regex if we don't have it already\n\t mom = createUTC([2000, i]);\n\t shortPieces.push(this.monthsShort(mom, ''));\n\t longPieces.push(this.months(mom, ''));\n\t mixedPieces.push(this.months(mom, ''));\n\t mixedPieces.push(this.monthsShort(mom, ''));\n\t }\n\t // Sorting makes sure if one month (or abbr) is a prefix of another it\n\t // will match the longer piece.\n\t shortPieces.sort(cmpLenRev);\n\t longPieces.sort(cmpLenRev);\n\t mixedPieces.sort(cmpLenRev);\n\t for (i = 0; i < 12; i++) {\n\t shortPieces[i] = regexEscape(shortPieces[i]);\n\t longPieces[i] = regexEscape(longPieces[i]);\n\t }\n\t for (i = 0; i < 24; i++) {\n\t mixedPieces[i] = regexEscape(mixedPieces[i]);\n\t }\n\t\n\t this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n\t this._monthsShortRegex = this._monthsRegex;\n\t this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n\t this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('Y', 0, 0, function () {\n\t var y = this.year();\n\t return y <= 9999 ? '' + y : '+' + y;\n\t});\n\t\n\taddFormatToken(0, ['YY', 2], 0, function () {\n\t return this.year() % 100;\n\t});\n\t\n\taddFormatToken(0, ['YYYY', 4], 0, 'year');\n\taddFormatToken(0, ['YYYYY', 5], 0, 'year');\n\taddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('year', 'y');\n\t\n\t// PRIORITIES\n\t\n\taddUnitPriority('year', 1);\n\t\n\t// PARSING\n\t\n\taddRegexToken('Y', matchSigned);\n\taddRegexToken('YY', match1to2, match2);\n\taddRegexToken('YYYY', match1to4, match4);\n\taddRegexToken('YYYYY', match1to6, match6);\n\taddRegexToken('YYYYYY', match1to6, match6);\n\t\n\taddParseToken(['YYYYY', 'YYYYYY'], YEAR);\n\taddParseToken('YYYY', function (input, array) {\n\t array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n\t});\n\taddParseToken('YY', function (input, array) {\n\t array[YEAR] = hooks.parseTwoDigitYear(input);\n\t});\n\taddParseToken('Y', function (input, array) {\n\t array[YEAR] = parseInt(input, 10);\n\t});\n\t\n\t// HELPERS\n\t\n\tfunction daysInYear(year) {\n\t return isLeapYear(year) ? 366 : 365;\n\t}\n\t\n\tfunction isLeapYear(year) {\n\t return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n\t}\n\t\n\t// HOOKS\n\t\n\thooks.parseTwoDigitYear = function (input) {\n\t return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n\t};\n\t\n\t// MOMENTS\n\t\n\tvar getSetYear = makeGetSet('FullYear', true);\n\t\n\tfunction getIsLeapYear () {\n\t return isLeapYear(this.year());\n\t}\n\t\n\tfunction createDate (y, m, d, h, M, s, ms) {\n\t //can't just apply() to create a date:\n\t //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply\n\t var date = new Date(y, m, d, h, M, s, ms);\n\t\n\t //the date constructor remaps years 0-99 to 1900-1999\n\t if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n\t date.setFullYear(y);\n\t }\n\t return date;\n\t}\n\t\n\tfunction createUTCDate (y) {\n\t var date = new Date(Date.UTC.apply(null, arguments));\n\t\n\t //the Date.UTC function remaps years 0-99 to 1900-1999\n\t if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n\t date.setUTCFullYear(y);\n\t }\n\t return date;\n\t}\n\t\n\t// start-of-first-week - start-of-year\n\tfunction firstWeekOffset(year, dow, doy) {\n\t var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n\t fwd = 7 + dow - doy,\n\t // first-week day local weekday -- which local weekday is fwd\n\t fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\t\n\t return -fwdlw + fwd - 1;\n\t}\n\t\n\t//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n\tfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n\t var localWeekday = (7 + weekday - dow) % 7,\n\t weekOffset = firstWeekOffset(year, dow, doy),\n\t dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n\t resYear, resDayOfYear;\n\t\n\t if (dayOfYear <= 0) {\n\t resYear = year - 1;\n\t resDayOfYear = daysInYear(resYear) + dayOfYear;\n\t } else if (dayOfYear > daysInYear(year)) {\n\t resYear = year + 1;\n\t resDayOfYear = dayOfYear - daysInYear(year);\n\t } else {\n\t resYear = year;\n\t resDayOfYear = dayOfYear;\n\t }\n\t\n\t return {\n\t year: resYear,\n\t dayOfYear: resDayOfYear\n\t };\n\t}\n\t\n\tfunction weekOfYear(mom, dow, doy) {\n\t var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n\t week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n\t resWeek, resYear;\n\t\n\t if (week < 1) {\n\t resYear = mom.year() - 1;\n\t resWeek = week + weeksInYear(resYear, dow, doy);\n\t } else if (week > weeksInYear(mom.year(), dow, doy)) {\n\t resWeek = week - weeksInYear(mom.year(), dow, doy);\n\t resYear = mom.year() + 1;\n\t } else {\n\t resYear = mom.year();\n\t resWeek = week;\n\t }\n\t\n\t return {\n\t week: resWeek,\n\t year: resYear\n\t };\n\t}\n\t\n\tfunction weeksInYear(year, dow, doy) {\n\t var weekOffset = firstWeekOffset(year, dow, doy),\n\t weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n\t return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('w', ['ww', 2], 'wo', 'week');\n\taddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('week', 'w');\n\taddUnitAlias('isoWeek', 'W');\n\t\n\t// PRIORITIES\n\t\n\taddUnitPriority('week', 5);\n\taddUnitPriority('isoWeek', 5);\n\t\n\t// PARSING\n\t\n\taddRegexToken('w', match1to2);\n\taddRegexToken('ww', match1to2, match2);\n\taddRegexToken('W', match1to2);\n\taddRegexToken('WW', match1to2, match2);\n\t\n\taddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n\t week[token.substr(0, 1)] = toInt(input);\n\t});\n\t\n\t// HELPERS\n\t\n\t// LOCALES\n\t\n\tfunction localeWeek (mom) {\n\t return weekOfYear(mom, this._week.dow, this._week.doy).week;\n\t}\n\t\n\tvar defaultLocaleWeek = {\n\t dow : 0, // Sunday is the first day of the week.\n\t doy : 6 // The week that contains Jan 1st is the first week of the year.\n\t};\n\t\n\tfunction localeFirstDayOfWeek () {\n\t return this._week.dow;\n\t}\n\t\n\tfunction localeFirstDayOfYear () {\n\t return this._week.doy;\n\t}\n\t\n\t// MOMENTS\n\t\n\tfunction getSetWeek (input) {\n\t var week = this.localeData().week(this);\n\t return input == null ? week : this.add((input - week) * 7, 'd');\n\t}\n\t\n\tfunction getSetISOWeek (input) {\n\t var week = weekOfYear(this, 1, 4).week;\n\t return input == null ? week : this.add((input - week) * 7, 'd');\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('d', 0, 'do', 'day');\n\t\n\taddFormatToken('dd', 0, 0, function (format) {\n\t return this.localeData().weekdaysMin(this, format);\n\t});\n\t\n\taddFormatToken('ddd', 0, 0, function (format) {\n\t return this.localeData().weekdaysShort(this, format);\n\t});\n\t\n\taddFormatToken('dddd', 0, 0, function (format) {\n\t return this.localeData().weekdays(this, format);\n\t});\n\t\n\taddFormatToken('e', 0, 0, 'weekday');\n\taddFormatToken('E', 0, 0, 'isoWeekday');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('day', 'd');\n\taddUnitAlias('weekday', 'e');\n\taddUnitAlias('isoWeekday', 'E');\n\t\n\t// PRIORITY\n\taddUnitPriority('day', 11);\n\taddUnitPriority('weekday', 11);\n\taddUnitPriority('isoWeekday', 11);\n\t\n\t// PARSING\n\t\n\taddRegexToken('d', match1to2);\n\taddRegexToken('e', match1to2);\n\taddRegexToken('E', match1to2);\n\taddRegexToken('dd', function (isStrict, locale) {\n\t return locale.weekdaysMinRegex(isStrict);\n\t});\n\taddRegexToken('ddd', function (isStrict, locale) {\n\t return locale.weekdaysShortRegex(isStrict);\n\t});\n\taddRegexToken('dddd', function (isStrict, locale) {\n\t return locale.weekdaysRegex(isStrict);\n\t});\n\t\n\taddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n\t var weekday = config._locale.weekdaysParse(input, token, config._strict);\n\t // if we didn't get a weekday name, mark the date as invalid\n\t if (weekday != null) {\n\t week.d = weekday;\n\t } else {\n\t getParsingFlags(config).invalidWeekday = input;\n\t }\n\t});\n\t\n\taddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n\t week[token] = toInt(input);\n\t});\n\t\n\t// HELPERS\n\t\n\tfunction parseWeekday(input, locale) {\n\t if (typeof input !== 'string') {\n\t return input;\n\t }\n\t\n\t if (!isNaN(input)) {\n\t return parseInt(input, 10);\n\t }\n\t\n\t input = locale.weekdaysParse(input);\n\t if (typeof input === 'number') {\n\t return input;\n\t }\n\t\n\t return null;\n\t}\n\t\n\tfunction parseIsoWeekday(input, locale) {\n\t if (typeof input === 'string') {\n\t return locale.weekdaysParse(input) % 7 || 7;\n\t }\n\t return isNaN(input) ? null : input;\n\t}\n\t\n\t// LOCALES\n\t\n\tvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n\tfunction localeWeekdays (m, format) {\n\t if (!m) {\n\t return this._weekdays;\n\t }\n\t return isArray(this._weekdays) ? this._weekdays[m.day()] :\n\t this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n\t}\n\t\n\tvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n\tfunction localeWeekdaysShort (m) {\n\t return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n\t}\n\t\n\tvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n\tfunction localeWeekdaysMin (m) {\n\t return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n\t}\n\t\n\tfunction handleStrictParse$1(weekdayName, format, strict) {\n\t var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n\t if (!this._weekdaysParse) {\n\t this._weekdaysParse = [];\n\t this._shortWeekdaysParse = [];\n\t this._minWeekdaysParse = [];\n\t\n\t for (i = 0; i < 7; ++i) {\n\t mom = createUTC([2000, 1]).day(i);\n\t this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n\t this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n\t this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n\t }\n\t }\n\t\n\t if (strict) {\n\t if (format === 'dddd') {\n\t ii = indexOf$1.call(this._weekdaysParse, llc);\n\t return ii !== -1 ? ii : null;\n\t } else if (format === 'ddd') {\n\t ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n\t return ii !== -1 ? ii : null;\n\t } else {\n\t ii = indexOf$1.call(this._minWeekdaysParse, llc);\n\t return ii !== -1 ? ii : null;\n\t }\n\t } else {\n\t if (format === 'dddd') {\n\t ii = indexOf$1.call(this._weekdaysParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._minWeekdaysParse, llc);\n\t return ii !== -1 ? ii : null;\n\t } else if (format === 'ddd') {\n\t ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._weekdaysParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._minWeekdaysParse, llc);\n\t return ii !== -1 ? ii : null;\n\t } else {\n\t ii = indexOf$1.call(this._minWeekdaysParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._weekdaysParse, llc);\n\t if (ii !== -1) {\n\t return ii;\n\t }\n\t ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n\t return ii !== -1 ? ii : null;\n\t }\n\t }\n\t}\n\t\n\tfunction localeWeekdaysParse (weekdayName, format, strict) {\n\t var i, mom, regex;\n\t\n\t if (this._weekdaysParseExact) {\n\t return handleStrictParse$1.call(this, weekdayName, format, strict);\n\t }\n\t\n\t if (!this._weekdaysParse) {\n\t this._weekdaysParse = [];\n\t this._minWeekdaysParse = [];\n\t this._shortWeekdaysParse = [];\n\t this._fullWeekdaysParse = [];\n\t }\n\t\n\t for (i = 0; i < 7; i++) {\n\t // make the regex if we don't have it already\n\t\n\t mom = createUTC([2000, 1]).day(i);\n\t if (strict && !this._fullWeekdaysParse[i]) {\n\t this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n\t this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n\t this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n\t }\n\t if (!this._weekdaysParse[i]) {\n\t regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n\t this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n\t }\n\t // test the regex\n\t if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n\t return i;\n\t } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n\t return i;\n\t } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n\t return i;\n\t } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n\t return i;\n\t }\n\t }\n\t}\n\t\n\t// MOMENTS\n\t\n\tfunction getSetDayOfWeek (input) {\n\t if (!this.isValid()) {\n\t return input != null ? this : NaN;\n\t }\n\t var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n\t if (input != null) {\n\t input = parseWeekday(input, this.localeData());\n\t return this.add(input - day, 'd');\n\t } else {\n\t return day;\n\t }\n\t}\n\t\n\tfunction getSetLocaleDayOfWeek (input) {\n\t if (!this.isValid()) {\n\t return input != null ? this : NaN;\n\t }\n\t var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n\t return input == null ? weekday : this.add(input - weekday, 'd');\n\t}\n\t\n\tfunction getSetISODayOfWeek (input) {\n\t if (!this.isValid()) {\n\t return input != null ? this : NaN;\n\t }\n\t\n\t // behaves the same as moment#day except\n\t // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n\t // as a setter, sunday should belong to the previous week.\n\t\n\t if (input != null) {\n\t var weekday = parseIsoWeekday(input, this.localeData());\n\t return this.day(this.day() % 7 ? weekday : weekday - 7);\n\t } else {\n\t return this.day() || 7;\n\t }\n\t}\n\t\n\tvar defaultWeekdaysRegex = matchWord;\n\tfunction weekdaysRegex (isStrict) {\n\t if (this._weekdaysParseExact) {\n\t if (!hasOwnProp(this, '_weekdaysRegex')) {\n\t computeWeekdaysParse.call(this);\n\t }\n\t if (isStrict) {\n\t return this._weekdaysStrictRegex;\n\t } else {\n\t return this._weekdaysRegex;\n\t }\n\t } else {\n\t if (!hasOwnProp(this, '_weekdaysRegex')) {\n\t this._weekdaysRegex = defaultWeekdaysRegex;\n\t }\n\t return this._weekdaysStrictRegex && isStrict ?\n\t this._weekdaysStrictRegex : this._weekdaysRegex;\n\t }\n\t}\n\t\n\tvar defaultWeekdaysShortRegex = matchWord;\n\tfunction weekdaysShortRegex (isStrict) {\n\t if (this._weekdaysParseExact) {\n\t if (!hasOwnProp(this, '_weekdaysRegex')) {\n\t computeWeekdaysParse.call(this);\n\t }\n\t if (isStrict) {\n\t return this._weekdaysShortStrictRegex;\n\t } else {\n\t return this._weekdaysShortRegex;\n\t }\n\t } else {\n\t if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n\t this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n\t }\n\t return this._weekdaysShortStrictRegex && isStrict ?\n\t this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n\t }\n\t}\n\t\n\tvar defaultWeekdaysMinRegex = matchWord;\n\tfunction weekdaysMinRegex (isStrict) {\n\t if (this._weekdaysParseExact) {\n\t if (!hasOwnProp(this, '_weekdaysRegex')) {\n\t computeWeekdaysParse.call(this);\n\t }\n\t if (isStrict) {\n\t return this._weekdaysMinStrictRegex;\n\t } else {\n\t return this._weekdaysMinRegex;\n\t }\n\t } else {\n\t if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n\t this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n\t }\n\t return this._weekdaysMinStrictRegex && isStrict ?\n\t this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n\t }\n\t}\n\t\n\t\n\tfunction computeWeekdaysParse () {\n\t function cmpLenRev(a, b) {\n\t return b.length - a.length;\n\t }\n\t\n\t var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n\t i, mom, minp, shortp, longp;\n\t for (i = 0; i < 7; i++) {\n\t // make the regex if we don't have it already\n\t mom = createUTC([2000, 1]).day(i);\n\t minp = this.weekdaysMin(mom, '');\n\t shortp = this.weekdaysShort(mom, '');\n\t longp = this.weekdays(mom, '');\n\t minPieces.push(minp);\n\t shortPieces.push(shortp);\n\t longPieces.push(longp);\n\t mixedPieces.push(minp);\n\t mixedPieces.push(shortp);\n\t mixedPieces.push(longp);\n\t }\n\t // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n\t // will match the longer piece.\n\t minPieces.sort(cmpLenRev);\n\t shortPieces.sort(cmpLenRev);\n\t longPieces.sort(cmpLenRev);\n\t mixedPieces.sort(cmpLenRev);\n\t for (i = 0; i < 7; i++) {\n\t shortPieces[i] = regexEscape(shortPieces[i]);\n\t longPieces[i] = regexEscape(longPieces[i]);\n\t mixedPieces[i] = regexEscape(mixedPieces[i]);\n\t }\n\t\n\t this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n\t this._weekdaysShortRegex = this._weekdaysRegex;\n\t this._weekdaysMinRegex = this._weekdaysRegex;\n\t\n\t this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n\t this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n\t this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n\t}\n\t\n\t// FORMATTING\n\t\n\tfunction hFormat() {\n\t return this.hours() % 12 || 12;\n\t}\n\t\n\tfunction kFormat() {\n\t return this.hours() || 24;\n\t}\n\t\n\taddFormatToken('H', ['HH', 2], 0, 'hour');\n\taddFormatToken('h', ['hh', 2], 0, hFormat);\n\taddFormatToken('k', ['kk', 2], 0, kFormat);\n\t\n\taddFormatToken('hmm', 0, 0, function () {\n\t return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n\t});\n\t\n\taddFormatToken('hmmss', 0, 0, function () {\n\t return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n\t zeroFill(this.seconds(), 2);\n\t});\n\t\n\taddFormatToken('Hmm', 0, 0, function () {\n\t return '' + this.hours() + zeroFill(this.minutes(), 2);\n\t});\n\t\n\taddFormatToken('Hmmss', 0, 0, function () {\n\t return '' + this.hours() + zeroFill(this.minutes(), 2) +\n\t zeroFill(this.seconds(), 2);\n\t});\n\t\n\tfunction meridiem (token, lowercase) {\n\t addFormatToken(token, 0, 0, function () {\n\t return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n\t });\n\t}\n\t\n\tmeridiem('a', true);\n\tmeridiem('A', false);\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('hour', 'h');\n\t\n\t// PRIORITY\n\taddUnitPriority('hour', 13);\n\t\n\t// PARSING\n\t\n\tfunction matchMeridiem (isStrict, locale) {\n\t return locale._meridiemParse;\n\t}\n\t\n\taddRegexToken('a', matchMeridiem);\n\taddRegexToken('A', matchMeridiem);\n\taddRegexToken('H', match1to2);\n\taddRegexToken('h', match1to2);\n\taddRegexToken('HH', match1to2, match2);\n\taddRegexToken('hh', match1to2, match2);\n\t\n\taddRegexToken('hmm', match3to4);\n\taddRegexToken('hmmss', match5to6);\n\taddRegexToken('Hmm', match3to4);\n\taddRegexToken('Hmmss', match5to6);\n\t\n\taddParseToken(['H', 'HH'], HOUR);\n\taddParseToken(['a', 'A'], function (input, array, config) {\n\t config._isPm = config._locale.isPM(input);\n\t config._meridiem = input;\n\t});\n\taddParseToken(['h', 'hh'], function (input, array, config) {\n\t array[HOUR] = toInt(input);\n\t getParsingFlags(config).bigHour = true;\n\t});\n\taddParseToken('hmm', function (input, array, config) {\n\t var pos = input.length - 2;\n\t array[HOUR] = toInt(input.substr(0, pos));\n\t array[MINUTE] = toInt(input.substr(pos));\n\t getParsingFlags(config).bigHour = true;\n\t});\n\taddParseToken('hmmss', function (input, array, config) {\n\t var pos1 = input.length - 4;\n\t var pos2 = input.length - 2;\n\t array[HOUR] = toInt(input.substr(0, pos1));\n\t array[MINUTE] = toInt(input.substr(pos1, 2));\n\t array[SECOND] = toInt(input.substr(pos2));\n\t getParsingFlags(config).bigHour = true;\n\t});\n\taddParseToken('Hmm', function (input, array, config) {\n\t var pos = input.length - 2;\n\t array[HOUR] = toInt(input.substr(0, pos));\n\t array[MINUTE] = toInt(input.substr(pos));\n\t});\n\taddParseToken('Hmmss', function (input, array, config) {\n\t var pos1 = input.length - 4;\n\t var pos2 = input.length - 2;\n\t array[HOUR] = toInt(input.substr(0, pos1));\n\t array[MINUTE] = toInt(input.substr(pos1, 2));\n\t array[SECOND] = toInt(input.substr(pos2));\n\t});\n\t\n\t// LOCALES\n\t\n\tfunction localeIsPM (input) {\n\t // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n\t // Using charAt should be more compatible.\n\t return ((input + '').toLowerCase().charAt(0) === 'p');\n\t}\n\t\n\tvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n\tfunction localeMeridiem (hours, minutes, isLower) {\n\t if (hours > 11) {\n\t return isLower ? 'pm' : 'PM';\n\t } else {\n\t return isLower ? 'am' : 'AM';\n\t }\n\t}\n\t\n\t\n\t// MOMENTS\n\t\n\t// Setting the hour should keep the time, because the user explicitly\n\t// specified which hour he wants. So trying to maintain the same hour (in\n\t// a new timezone) makes sense. Adding/subtracting hours does not follow\n\t// this rule.\n\tvar getSetHour = makeGetSet('Hours', true);\n\t\n\t// months\n\t// week\n\t// weekdays\n\t// meridiem\n\tvar baseConfig = {\n\t calendar: defaultCalendar,\n\t longDateFormat: defaultLongDateFormat,\n\t invalidDate: defaultInvalidDate,\n\t ordinal: defaultOrdinal,\n\t ordinalParse: defaultOrdinalParse,\n\t relativeTime: defaultRelativeTime,\n\t\n\t months: defaultLocaleMonths,\n\t monthsShort: defaultLocaleMonthsShort,\n\t\n\t week: defaultLocaleWeek,\n\t\n\t weekdays: defaultLocaleWeekdays,\n\t weekdaysMin: defaultLocaleWeekdaysMin,\n\t weekdaysShort: defaultLocaleWeekdaysShort,\n\t\n\t meridiemParse: defaultLocaleMeridiemParse\n\t};\n\t\n\t// internal storage for locale config files\n\tvar locales = {};\n\tvar localeFamilies = {};\n\tvar globalLocale;\n\t\n\tfunction normalizeLocale(key) {\n\t return key ? key.toLowerCase().replace('_', '-') : key;\n\t}\n\t\n\t// pick the locale from the array\n\t// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n\t// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n\tfunction chooseLocale(names) {\n\t var i = 0, j, next, locale, split;\n\t\n\t while (i < names.length) {\n\t split = normalizeLocale(names[i]).split('-');\n\t j = split.length;\n\t next = normalizeLocale(names[i + 1]);\n\t next = next ? next.split('-') : null;\n\t while (j > 0) {\n\t locale = loadLocale(split.slice(0, j).join('-'));\n\t if (locale) {\n\t return locale;\n\t }\n\t if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n\t //the next array item is better than a shallower substring of this one\n\t break;\n\t }\n\t j--;\n\t }\n\t i++;\n\t }\n\t return null;\n\t}\n\t\n\tfunction loadLocale(name) {\n\t var oldLocale = null;\n\t // TODO: Find a better way to register and load all the locales in Node\n\t if (!locales[name] && (typeof module !== 'undefined') &&\n\t module && module.exports) {\n\t try {\n\t oldLocale = globalLocale._abbr;\n\t __webpack_require__(248)(\"./\" + name);\n\t // because defineLocale currently also sets the global locale, we\n\t // want to undo that for lazy loaded locales\n\t getSetGlobalLocale(oldLocale);\n\t } catch (e) { }\n\t }\n\t return locales[name];\n\t}\n\t\n\t// This function will load locale and then set the global locale. If\n\t// no arguments are passed in, it will simply return the current global\n\t// locale key.\n\tfunction getSetGlobalLocale (key, values) {\n\t var data;\n\t if (key) {\n\t if (isUndefined(values)) {\n\t data = getLocale(key);\n\t }\n\t else {\n\t data = defineLocale(key, values);\n\t }\n\t\n\t if (data) {\n\t // moment.duration._locale = moment._locale = data;\n\t globalLocale = data;\n\t }\n\t }\n\t\n\t return globalLocale._abbr;\n\t}\n\t\n\tfunction defineLocale (name, config) {\n\t if (config !== null) {\n\t var parentConfig = baseConfig;\n\t config.abbr = name;\n\t if (locales[name] != null) {\n\t deprecateSimple('defineLocaleOverride',\n\t 'use moment.updateLocale(localeName, config) to change ' +\n\t 'an existing locale. moment.defineLocale(localeName, ' +\n\t 'config) should only be used for creating a new locale ' +\n\t 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n\t parentConfig = locales[name]._config;\n\t } else if (config.parentLocale != null) {\n\t if (locales[config.parentLocale] != null) {\n\t parentConfig = locales[config.parentLocale]._config;\n\t } else {\n\t if (!localeFamilies[config.parentLocale]) {\n\t localeFamilies[config.parentLocale] = [];\n\t }\n\t localeFamilies[config.parentLocale].push({\n\t name: name,\n\t config: config\n\t });\n\t return null;\n\t }\n\t }\n\t locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\t\n\t if (localeFamilies[name]) {\n\t localeFamilies[name].forEach(function (x) {\n\t defineLocale(x.name, x.config);\n\t });\n\t }\n\t\n\t // backwards compat for now: also set the locale\n\t // make sure we set the locale AFTER all child locales have been\n\t // created, so we won't end up with the child locale set.\n\t getSetGlobalLocale(name);\n\t\n\t\n\t return locales[name];\n\t } else {\n\t // useful for testing\n\t delete locales[name];\n\t return null;\n\t }\n\t}\n\t\n\tfunction updateLocale(name, config) {\n\t if (config != null) {\n\t var locale, parentConfig = baseConfig;\n\t // MERGE\n\t if (locales[name] != null) {\n\t parentConfig = locales[name]._config;\n\t }\n\t config = mergeConfigs(parentConfig, config);\n\t locale = new Locale(config);\n\t locale.parentLocale = locales[name];\n\t locales[name] = locale;\n\t\n\t // backwards compat for now: also set the locale\n\t getSetGlobalLocale(name);\n\t } else {\n\t // pass null for config to unupdate, useful for tests\n\t if (locales[name] != null) {\n\t if (locales[name].parentLocale != null) {\n\t locales[name] = locales[name].parentLocale;\n\t } else if (locales[name] != null) {\n\t delete locales[name];\n\t }\n\t }\n\t }\n\t return locales[name];\n\t}\n\t\n\t// returns locale data\n\tfunction getLocale (key) {\n\t var locale;\n\t\n\t if (key && key._locale && key._locale._abbr) {\n\t key = key._locale._abbr;\n\t }\n\t\n\t if (!key) {\n\t return globalLocale;\n\t }\n\t\n\t if (!isArray(key)) {\n\t //short-circuit everything else\n\t locale = loadLocale(key);\n\t if (locale) {\n\t return locale;\n\t }\n\t key = [key];\n\t }\n\t\n\t return chooseLocale(key);\n\t}\n\t\n\tfunction listLocales() {\n\t return keys$1(locales);\n\t}\n\t\n\tfunction checkOverflow (m) {\n\t var overflow;\n\t var a = m._a;\n\t\n\t if (a && getParsingFlags(m).overflow === -2) {\n\t overflow =\n\t a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :\n\t a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n\t a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n\t a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE :\n\t a[SECOND] < 0 || a[SECOND] > 59 ? SECOND :\n\t a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n\t -1;\n\t\n\t if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n\t overflow = DATE;\n\t }\n\t if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n\t overflow = WEEK;\n\t }\n\t if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n\t overflow = WEEKDAY;\n\t }\n\t\n\t getParsingFlags(m).overflow = overflow;\n\t }\n\t\n\t return m;\n\t}\n\t\n\t// iso 8601 regex\n\t// 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)\n\tvar 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)?)?$/;\n\tvar 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)?)?$/;\n\t\n\tvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\t\n\tvar isoDates = [\n\t ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n\t ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n\t ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n\t ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n\t ['YYYY-DDD', /\\d{4}-\\d{3}/],\n\t ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n\t ['YYYYYYMMDD', /[+-]\\d{10}/],\n\t ['YYYYMMDD', /\\d{8}/],\n\t // YYYYMM is NOT allowed by the standard\n\t ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n\t ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n\t ['YYYYDDD', /\\d{7}/]\n\t];\n\t\n\t// iso time formats and regexes\n\tvar isoTimes = [\n\t ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n\t ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n\t ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n\t ['HH:mm', /\\d\\d:\\d\\d/],\n\t ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n\t ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n\t ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n\t ['HHmm', /\\d\\d\\d\\d/],\n\t ['HH', /\\d\\d/]\n\t];\n\t\n\tvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\t\n\t// date from iso format\n\tfunction configFromISO(config) {\n\t var i, l,\n\t string = config._i,\n\t match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n\t allowTime, dateFormat, timeFormat, tzFormat;\n\t\n\t if (match) {\n\t getParsingFlags(config).iso = true;\n\t\n\t for (i = 0, l = isoDates.length; i < l; i++) {\n\t if (isoDates[i][1].exec(match[1])) {\n\t dateFormat = isoDates[i][0];\n\t allowTime = isoDates[i][2] !== false;\n\t break;\n\t }\n\t }\n\t if (dateFormat == null) {\n\t config._isValid = false;\n\t return;\n\t }\n\t if (match[3]) {\n\t for (i = 0, l = isoTimes.length; i < l; i++) {\n\t if (isoTimes[i][1].exec(match[3])) {\n\t // match[2] should be 'T' or space\n\t timeFormat = (match[2] || ' ') + isoTimes[i][0];\n\t break;\n\t }\n\t }\n\t if (timeFormat == null) {\n\t config._isValid = false;\n\t return;\n\t }\n\t }\n\t if (!allowTime && timeFormat != null) {\n\t config._isValid = false;\n\t return;\n\t }\n\t if (match[4]) {\n\t if (tzRegex.exec(match[4])) {\n\t tzFormat = 'Z';\n\t } else {\n\t config._isValid = false;\n\t return;\n\t }\n\t }\n\t config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n\t configFromStringAndFormat(config);\n\t } else {\n\t config._isValid = false;\n\t }\n\t}\n\t\n\t// date from iso format or fallback\n\tfunction configFromString(config) {\n\t var matched = aspNetJsonRegex.exec(config._i);\n\t\n\t if (matched !== null) {\n\t config._d = new Date(+matched[1]);\n\t return;\n\t }\n\t\n\t configFromISO(config);\n\t if (config._isValid === false) {\n\t delete config._isValid;\n\t hooks.createFromInputFallback(config);\n\t }\n\t}\n\t\n\thooks.createFromInputFallback = deprecate(\n\t 'value provided is not in a recognized ISO format. moment construction falls back to js Date(), ' +\n\t 'which is not reliable across all browsers and versions. Non ISO date formats are ' +\n\t 'discouraged and will be removed in an upcoming major release. Please refer to ' +\n\t 'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n\t function (config) {\n\t config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n\t }\n\t);\n\t\n\t// Pick the first defined of two or three arguments.\n\tfunction defaults(a, b, c) {\n\t if (a != null) {\n\t return a;\n\t }\n\t if (b != null) {\n\t return b;\n\t }\n\t return c;\n\t}\n\t\n\tfunction currentDateArray(config) {\n\t // hooks is actually the exported moment object\n\t var nowValue = new Date(hooks.now());\n\t if (config._useUTC) {\n\t return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n\t }\n\t return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n\t}\n\t\n\t// convert an array to a date.\n\t// the array should mirror the parameters below\n\t// note: all values past the year are optional and will default to the lowest possible value.\n\t// [year, month, day , hour, minute, second, millisecond]\n\tfunction configFromArray (config) {\n\t var i, date, input = [], currentDate, yearToUse;\n\t\n\t if (config._d) {\n\t return;\n\t }\n\t\n\t currentDate = currentDateArray(config);\n\t\n\t //compute day of the year from weeks and weekdays\n\t if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n\t dayOfYearFromWeekInfo(config);\n\t }\n\t\n\t //if the day of the year is set, figure out what it is\n\t if (config._dayOfYear) {\n\t yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\t\n\t if (config._dayOfYear > daysInYear(yearToUse)) {\n\t getParsingFlags(config)._overflowDayOfYear = true;\n\t }\n\t\n\t date = createUTCDate(yearToUse, 0, config._dayOfYear);\n\t config._a[MONTH] = date.getUTCMonth();\n\t config._a[DATE] = date.getUTCDate();\n\t }\n\t\n\t // Default to current date.\n\t // * if no year, month, day of month are given, default to today\n\t // * if day of month is given, default month and year\n\t // * if month is given, default only year\n\t // * if year is given, don't default anything\n\t for (i = 0; i < 3 && config._a[i] == null; ++i) {\n\t config._a[i] = input[i] = currentDate[i];\n\t }\n\t\n\t // Zero out whatever was not defaulted, including time\n\t for (; i < 7; i++) {\n\t config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n\t }\n\t\n\t // Check for 24:00:00.000\n\t if (config._a[HOUR] === 24 &&\n\t config._a[MINUTE] === 0 &&\n\t config._a[SECOND] === 0 &&\n\t config._a[MILLISECOND] === 0) {\n\t config._nextDay = true;\n\t config._a[HOUR] = 0;\n\t }\n\t\n\t config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n\t // Apply timezone offset from input. The actual utcOffset can be changed\n\t // with parseZone.\n\t if (config._tzm != null) {\n\t config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n\t }\n\t\n\t if (config._nextDay) {\n\t config._a[HOUR] = 24;\n\t }\n\t}\n\t\n\tfunction dayOfYearFromWeekInfo(config) {\n\t var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\t\n\t w = config._w;\n\t if (w.GG != null || w.W != null || w.E != null) {\n\t dow = 1;\n\t doy = 4;\n\t\n\t // TODO: We need to take the current isoWeekYear, but that depends on\n\t // how we interpret now (local, utc, fixed offset). So create\n\t // a now version of current config (take local/utc/offset flags, and\n\t // create now).\n\t weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n\t week = defaults(w.W, 1);\n\t weekday = defaults(w.E, 1);\n\t if (weekday < 1 || weekday > 7) {\n\t weekdayOverflow = true;\n\t }\n\t } else {\n\t dow = config._locale._week.dow;\n\t doy = config._locale._week.doy;\n\t\n\t var curWeek = weekOfYear(createLocal(), dow, doy);\n\t\n\t weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\t\n\t // Default to current week.\n\t week = defaults(w.w, curWeek.week);\n\t\n\t if (w.d != null) {\n\t // weekday -- low day numbers are considered next week\n\t weekday = w.d;\n\t if (weekday < 0 || weekday > 6) {\n\t weekdayOverflow = true;\n\t }\n\t } else if (w.e != null) {\n\t // local weekday -- counting starts from begining of week\n\t weekday = w.e + dow;\n\t if (w.e < 0 || w.e > 6) {\n\t weekdayOverflow = true;\n\t }\n\t } else {\n\t // default to begining of week\n\t weekday = dow;\n\t }\n\t }\n\t if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n\t getParsingFlags(config)._overflowWeeks = true;\n\t } else if (weekdayOverflow != null) {\n\t getParsingFlags(config)._overflowWeekday = true;\n\t } else {\n\t temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n\t config._a[YEAR] = temp.year;\n\t config._dayOfYear = temp.dayOfYear;\n\t }\n\t}\n\t\n\t// constant that refers to the ISO standard\n\thooks.ISO_8601 = function () {};\n\t\n\t// date from string and format string\n\tfunction configFromStringAndFormat(config) {\n\t // TODO: Move this to another part of the creation flow to prevent circular deps\n\t if (config._f === hooks.ISO_8601) {\n\t configFromISO(config);\n\t return;\n\t }\n\t\n\t config._a = [];\n\t getParsingFlags(config).empty = true;\n\t\n\t // This array is used to make a Date, either with `new Date` or `Date.UTC`\n\t var string = '' + config._i,\n\t i, parsedInput, tokens, token, skipped,\n\t stringLength = string.length,\n\t totalParsedInputLength = 0;\n\t\n\t tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\t\n\t for (i = 0; i < tokens.length; i++) {\n\t token = tokens[i];\n\t parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n\t // console.log('token', token, 'parsedInput', parsedInput,\n\t // 'regex', getParseRegexForToken(token, config));\n\t if (parsedInput) {\n\t skipped = string.substr(0, string.indexOf(parsedInput));\n\t if (skipped.length > 0) {\n\t getParsingFlags(config).unusedInput.push(skipped);\n\t }\n\t string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n\t totalParsedInputLength += parsedInput.length;\n\t }\n\t // don't parse if it's not a known token\n\t if (formatTokenFunctions[token]) {\n\t if (parsedInput) {\n\t getParsingFlags(config).empty = false;\n\t }\n\t else {\n\t getParsingFlags(config).unusedTokens.push(token);\n\t }\n\t addTimeToArrayFromToken(token, parsedInput, config);\n\t }\n\t else if (config._strict && !parsedInput) {\n\t getParsingFlags(config).unusedTokens.push(token);\n\t }\n\t }\n\t\n\t // add remaining unparsed input length to the string\n\t getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n\t if (string.length > 0) {\n\t getParsingFlags(config).unusedInput.push(string);\n\t }\n\t\n\t // clear _12h flag if hour is <= 12\n\t if (config._a[HOUR] <= 12 &&\n\t getParsingFlags(config).bigHour === true &&\n\t config._a[HOUR] > 0) {\n\t getParsingFlags(config).bigHour = undefined;\n\t }\n\t\n\t getParsingFlags(config).parsedDateParts = config._a.slice(0);\n\t getParsingFlags(config).meridiem = config._meridiem;\n\t // handle meridiem\n\t config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\t\n\t configFromArray(config);\n\t checkOverflow(config);\n\t}\n\t\n\t\n\tfunction meridiemFixWrap (locale, hour, meridiem) {\n\t var isPm;\n\t\n\t if (meridiem == null) {\n\t // nothing to do\n\t return hour;\n\t }\n\t if (locale.meridiemHour != null) {\n\t return locale.meridiemHour(hour, meridiem);\n\t } else if (locale.isPM != null) {\n\t // Fallback\n\t isPm = locale.isPM(meridiem);\n\t if (isPm && hour < 12) {\n\t hour += 12;\n\t }\n\t if (!isPm && hour === 12) {\n\t hour = 0;\n\t }\n\t return hour;\n\t } else {\n\t // this is not supposed to happen\n\t return hour;\n\t }\n\t}\n\t\n\t// date from string and array of format strings\n\tfunction configFromStringAndArray(config) {\n\t var tempConfig,\n\t bestMoment,\n\t\n\t scoreToBeat,\n\t i,\n\t currentScore;\n\t\n\t if (config._f.length === 0) {\n\t getParsingFlags(config).invalidFormat = true;\n\t config._d = new Date(NaN);\n\t return;\n\t }\n\t\n\t for (i = 0; i < config._f.length; i++) {\n\t currentScore = 0;\n\t tempConfig = copyConfig({}, config);\n\t if (config._useUTC != null) {\n\t tempConfig._useUTC = config._useUTC;\n\t }\n\t tempConfig._f = config._f[i];\n\t configFromStringAndFormat(tempConfig);\n\t\n\t if (!isValid(tempConfig)) {\n\t continue;\n\t }\n\t\n\t // if there is any input that was not parsed add a penalty for that format\n\t currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\t\n\t //or tokens\n\t currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\t\n\t getParsingFlags(tempConfig).score = currentScore;\n\t\n\t if (scoreToBeat == null || currentScore < scoreToBeat) {\n\t scoreToBeat = currentScore;\n\t bestMoment = tempConfig;\n\t }\n\t }\n\t\n\t extend(config, bestMoment || tempConfig);\n\t}\n\t\n\tfunction configFromObject(config) {\n\t if (config._d) {\n\t return;\n\t }\n\t\n\t var i = normalizeObjectUnits(config._i);\n\t config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n\t return obj && parseInt(obj, 10);\n\t });\n\t\n\t configFromArray(config);\n\t}\n\t\n\tfunction createFromConfig (config) {\n\t var res = new Moment(checkOverflow(prepareConfig(config)));\n\t if (res._nextDay) {\n\t // Adding is smart enough around DST\n\t res.add(1, 'd');\n\t res._nextDay = undefined;\n\t }\n\t\n\t return res;\n\t}\n\t\n\tfunction prepareConfig (config) {\n\t var input = config._i,\n\t format = config._f;\n\t\n\t config._locale = config._locale || getLocale(config._l);\n\t\n\t if (input === null || (format === undefined && input === '')) {\n\t return createInvalid({nullInput: true});\n\t }\n\t\n\t if (typeof input === 'string') {\n\t config._i = input = config._locale.preparse(input);\n\t }\n\t\n\t if (isMoment(input)) {\n\t return new Moment(checkOverflow(input));\n\t } else if (isDate(input)) {\n\t config._d = input;\n\t } else if (isArray(format)) {\n\t configFromStringAndArray(config);\n\t } else if (format) {\n\t configFromStringAndFormat(config);\n\t } else {\n\t configFromInput(config);\n\t }\n\t\n\t if (!isValid(config)) {\n\t config._d = null;\n\t }\n\t\n\t return config;\n\t}\n\t\n\tfunction configFromInput(config) {\n\t var input = config._i;\n\t if (input === undefined) {\n\t config._d = new Date(hooks.now());\n\t } else if (isDate(input)) {\n\t config._d = new Date(input.valueOf());\n\t } else if (typeof input === 'string') {\n\t configFromString(config);\n\t } else if (isArray(input)) {\n\t config._a = map(input.slice(0), function (obj) {\n\t return parseInt(obj, 10);\n\t });\n\t configFromArray(config);\n\t } else if (typeof(input) === 'object') {\n\t configFromObject(config);\n\t } else if (isNumber(input)) {\n\t // from milliseconds\n\t config._d = new Date(input);\n\t } else {\n\t hooks.createFromInputFallback(config);\n\t }\n\t}\n\t\n\tfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n\t var c = {};\n\t\n\t if (locale === true || locale === false) {\n\t strict = locale;\n\t locale = undefined;\n\t }\n\t\n\t if ((isObject(input) && isObjectEmpty(input)) ||\n\t (isArray(input) && input.length === 0)) {\n\t input = undefined;\n\t }\n\t // object construction must be done this way.\n\t // https://github.com/moment/moment/issues/1423\n\t c._isAMomentObject = true;\n\t c._useUTC = c._isUTC = isUTC;\n\t c._l = locale;\n\t c._i = input;\n\t c._f = format;\n\t c._strict = strict;\n\t\n\t return createFromConfig(c);\n\t}\n\t\n\tfunction createLocal (input, format, locale, strict) {\n\t return createLocalOrUTC(input, format, locale, strict, false);\n\t}\n\t\n\tvar prototypeMin = deprecate(\n\t 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n\t function () {\n\t var other = createLocal.apply(null, arguments);\n\t if (this.isValid() && other.isValid()) {\n\t return other < this ? this : other;\n\t } else {\n\t return createInvalid();\n\t }\n\t }\n\t);\n\t\n\tvar prototypeMax = deprecate(\n\t 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n\t function () {\n\t var other = createLocal.apply(null, arguments);\n\t if (this.isValid() && other.isValid()) {\n\t return other > this ? this : other;\n\t } else {\n\t return createInvalid();\n\t }\n\t }\n\t);\n\t\n\t// Pick a moment m from moments so that m[fn](other) is true for all\n\t// other. This relies on the function fn to be transitive.\n\t//\n\t// moments should either be an array of moment objects or an array, whose\n\t// first element is an array of moment objects.\n\tfunction pickBy(fn, moments) {\n\t var res, i;\n\t if (moments.length === 1 && isArray(moments[0])) {\n\t moments = moments[0];\n\t }\n\t if (!moments.length) {\n\t return createLocal();\n\t }\n\t res = moments[0];\n\t for (i = 1; i < moments.length; ++i) {\n\t if (!moments[i].isValid() || moments[i][fn](res)) {\n\t res = moments[i];\n\t }\n\t }\n\t return res;\n\t}\n\t\n\t// TODO: Use [].sort instead?\n\tfunction min () {\n\t var args = [].slice.call(arguments, 0);\n\t\n\t return pickBy('isBefore', args);\n\t}\n\t\n\tfunction max () {\n\t var args = [].slice.call(arguments, 0);\n\t\n\t return pickBy('isAfter', args);\n\t}\n\t\n\tvar now = function () {\n\t return Date.now ? Date.now() : +(new Date());\n\t};\n\t\n\tfunction Duration (duration) {\n\t var normalizedInput = normalizeObjectUnits(duration),\n\t years = normalizedInput.year || 0,\n\t quarters = normalizedInput.quarter || 0,\n\t months = normalizedInput.month || 0,\n\t weeks = normalizedInput.week || 0,\n\t days = normalizedInput.day || 0,\n\t hours = normalizedInput.hour || 0,\n\t minutes = normalizedInput.minute || 0,\n\t seconds = normalizedInput.second || 0,\n\t milliseconds = normalizedInput.millisecond || 0;\n\t\n\t // representation for dateAddRemove\n\t this._milliseconds = +milliseconds +\n\t seconds * 1e3 + // 1000\n\t minutes * 6e4 + // 1000 * 60\n\t hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n\t // Because of dateAddRemove treats 24 hours as different from a\n\t // day when working around DST, we need to store them separately\n\t this._days = +days +\n\t weeks * 7;\n\t // It is impossible translate months into days without knowing\n\t // which months you are are talking about, so we have to store\n\t // it separately.\n\t this._months = +months +\n\t quarters * 3 +\n\t years * 12;\n\t\n\t this._data = {};\n\t\n\t this._locale = getLocale();\n\t\n\t this._bubble();\n\t}\n\t\n\tfunction isDuration (obj) {\n\t return obj instanceof Duration;\n\t}\n\t\n\tfunction absRound (number) {\n\t if (number < 0) {\n\t return Math.round(-1 * number) * -1;\n\t } else {\n\t return Math.round(number);\n\t }\n\t}\n\t\n\t// FORMATTING\n\t\n\tfunction offset (token, separator) {\n\t addFormatToken(token, 0, 0, function () {\n\t var offset = this.utcOffset();\n\t var sign = '+';\n\t if (offset < 0) {\n\t offset = -offset;\n\t sign = '-';\n\t }\n\t return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n\t });\n\t}\n\t\n\toffset('Z', ':');\n\toffset('ZZ', '');\n\t\n\t// PARSING\n\t\n\taddRegexToken('Z', matchShortOffset);\n\taddRegexToken('ZZ', matchShortOffset);\n\taddParseToken(['Z', 'ZZ'], function (input, array, config) {\n\t config._useUTC = true;\n\t config._tzm = offsetFromString(matchShortOffset, input);\n\t});\n\t\n\t// HELPERS\n\t\n\t// timezone chunker\n\t// '+10:00' > ['10', '00']\n\t// '-1530' > ['-15', '30']\n\tvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\t\n\tfunction offsetFromString(matcher, string) {\n\t var matches = (string || '').match(matcher);\n\t\n\t if (matches === null) {\n\t return null;\n\t }\n\t\n\t var chunk = matches[matches.length - 1] || [];\n\t var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n\t var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\t\n\t return minutes === 0 ?\n\t 0 :\n\t parts[0] === '+' ? minutes : -minutes;\n\t}\n\t\n\t// Return a moment from input, that is local/utc/zone equivalent to model.\n\tfunction cloneWithOffset(input, model) {\n\t var res, diff;\n\t if (model._isUTC) {\n\t res = model.clone();\n\t diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n\t // Use low-level api, because this fn is low-level api.\n\t res._d.setTime(res._d.valueOf() + diff);\n\t hooks.updateOffset(res, false);\n\t return res;\n\t } else {\n\t return createLocal(input).local();\n\t }\n\t}\n\t\n\tfunction getDateOffset (m) {\n\t // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n\t // https://github.com/moment/moment/pull/1871\n\t return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n\t}\n\t\n\t// HOOKS\n\t\n\t// This function will be called whenever a moment is mutated.\n\t// It is intended to keep the offset in sync with the timezone.\n\thooks.updateOffset = function () {};\n\t\n\t// MOMENTS\n\t\n\t// keepLocalTime = true means only change the timezone, without\n\t// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n\t// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n\t// +0200, so we adjust the time as needed, to be valid.\n\t//\n\t// Keeping the time actually adds/subtracts (one hour)\n\t// from the actual represented time. That is why we call updateOffset\n\t// a second time. In case it wants us to change the offset again\n\t// _changeInProgress == true case, then we have to adjust, because\n\t// there is no such time in the given timezone.\n\tfunction getSetOffset (input, keepLocalTime) {\n\t var offset = this._offset || 0,\n\t localAdjust;\n\t if (!this.isValid()) {\n\t return input != null ? this : NaN;\n\t }\n\t if (input != null) {\n\t if (typeof input === 'string') {\n\t input = offsetFromString(matchShortOffset, input);\n\t if (input === null) {\n\t return this;\n\t }\n\t } else if (Math.abs(input) < 16) {\n\t input = input * 60;\n\t }\n\t if (!this._isUTC && keepLocalTime) {\n\t localAdjust = getDateOffset(this);\n\t }\n\t this._offset = input;\n\t this._isUTC = true;\n\t if (localAdjust != null) {\n\t this.add(localAdjust, 'm');\n\t }\n\t if (offset !== input) {\n\t if (!keepLocalTime || this._changeInProgress) {\n\t addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n\t } else if (!this._changeInProgress) {\n\t this._changeInProgress = true;\n\t hooks.updateOffset(this, true);\n\t this._changeInProgress = null;\n\t }\n\t }\n\t return this;\n\t } else {\n\t return this._isUTC ? offset : getDateOffset(this);\n\t }\n\t}\n\t\n\tfunction getSetZone (input, keepLocalTime) {\n\t if (input != null) {\n\t if (typeof input !== 'string') {\n\t input = -input;\n\t }\n\t\n\t this.utcOffset(input, keepLocalTime);\n\t\n\t return this;\n\t } else {\n\t return -this.utcOffset();\n\t }\n\t}\n\t\n\tfunction setOffsetToUTC (keepLocalTime) {\n\t return this.utcOffset(0, keepLocalTime);\n\t}\n\t\n\tfunction setOffsetToLocal (keepLocalTime) {\n\t if (this._isUTC) {\n\t this.utcOffset(0, keepLocalTime);\n\t this._isUTC = false;\n\t\n\t if (keepLocalTime) {\n\t this.subtract(getDateOffset(this), 'm');\n\t }\n\t }\n\t return this;\n\t}\n\t\n\tfunction setOffsetToParsedOffset () {\n\t if (this._tzm != null) {\n\t this.utcOffset(this._tzm);\n\t } else if (typeof this._i === 'string') {\n\t var tZone = offsetFromString(matchOffset, this._i);\n\t if (tZone != null) {\n\t this.utcOffset(tZone);\n\t }\n\t else {\n\t this.utcOffset(0, true);\n\t }\n\t }\n\t return this;\n\t}\n\t\n\tfunction hasAlignedHourOffset (input) {\n\t if (!this.isValid()) {\n\t return false;\n\t }\n\t input = input ? createLocal(input).utcOffset() : 0;\n\t\n\t return (this.utcOffset() - input) % 60 === 0;\n\t}\n\t\n\tfunction isDaylightSavingTime () {\n\t return (\n\t this.utcOffset() > this.clone().month(0).utcOffset() ||\n\t this.utcOffset() > this.clone().month(5).utcOffset()\n\t );\n\t}\n\t\n\tfunction isDaylightSavingTimeShifted () {\n\t if (!isUndefined(this._isDSTShifted)) {\n\t return this._isDSTShifted;\n\t }\n\t\n\t var c = {};\n\t\n\t copyConfig(c, this);\n\t c = prepareConfig(c);\n\t\n\t if (c._a) {\n\t var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n\t this._isDSTShifted = this.isValid() &&\n\t compareArrays(c._a, other.toArray()) > 0;\n\t } else {\n\t this._isDSTShifted = false;\n\t }\n\t\n\t return this._isDSTShifted;\n\t}\n\t\n\tfunction isLocal () {\n\t return this.isValid() ? !this._isUTC : false;\n\t}\n\t\n\tfunction isUtcOffset () {\n\t return this.isValid() ? this._isUTC : false;\n\t}\n\t\n\tfunction isUtc () {\n\t return this.isValid() ? this._isUTC && this._offset === 0 : false;\n\t}\n\t\n\t// ASP.NET json date format regex\n\tvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\t\n\t// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n\t// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n\t// and further modified to allow for strings containing both week and day\n\tvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\t\n\tfunction createDuration (input, key) {\n\t var duration = input,\n\t // matching against regexp is expensive, do it on demand\n\t match = null,\n\t sign,\n\t ret,\n\t diffRes;\n\t\n\t if (isDuration(input)) {\n\t duration = {\n\t ms : input._milliseconds,\n\t d : input._days,\n\t M : input._months\n\t };\n\t } else if (isNumber(input)) {\n\t duration = {};\n\t if (key) {\n\t duration[key] = input;\n\t } else {\n\t duration.milliseconds = input;\n\t }\n\t } else if (!!(match = aspNetRegex.exec(input))) {\n\t sign = (match[1] === '-') ? -1 : 1;\n\t duration = {\n\t y : 0,\n\t d : toInt(match[DATE]) * sign,\n\t h : toInt(match[HOUR]) * sign,\n\t m : toInt(match[MINUTE]) * sign,\n\t s : toInt(match[SECOND]) * sign,\n\t ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n\t };\n\t } else if (!!(match = isoRegex.exec(input))) {\n\t sign = (match[1] === '-') ? -1 : 1;\n\t duration = {\n\t y : parseIso(match[2], sign),\n\t M : parseIso(match[3], sign),\n\t w : parseIso(match[4], sign),\n\t d : parseIso(match[5], sign),\n\t h : parseIso(match[6], sign),\n\t m : parseIso(match[7], sign),\n\t s : parseIso(match[8], sign)\n\t };\n\t } else if (duration == null) {// checks for null or undefined\n\t duration = {};\n\t } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n\t diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\t\n\t duration = {};\n\t duration.ms = diffRes.milliseconds;\n\t duration.M = diffRes.months;\n\t }\n\t\n\t ret = new Duration(duration);\n\t\n\t if (isDuration(input) && hasOwnProp(input, '_locale')) {\n\t ret._locale = input._locale;\n\t }\n\t\n\t return ret;\n\t}\n\t\n\tcreateDuration.fn = Duration.prototype;\n\t\n\tfunction parseIso (inp, sign) {\n\t // We'd normally use ~~inp for this, but unfortunately it also\n\t // converts floats to ints.\n\t // inp may be undefined, so careful calling replace on it.\n\t var res = inp && parseFloat(inp.replace(',', '.'));\n\t // apply sign while we're at it\n\t return (isNaN(res) ? 0 : res) * sign;\n\t}\n\t\n\tfunction positiveMomentsDifference(base, other) {\n\t var res = {milliseconds: 0, months: 0};\n\t\n\t res.months = other.month() - base.month() +\n\t (other.year() - base.year()) * 12;\n\t if (base.clone().add(res.months, 'M').isAfter(other)) {\n\t --res.months;\n\t }\n\t\n\t res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\t\n\t return res;\n\t}\n\t\n\tfunction momentsDifference(base, other) {\n\t var res;\n\t if (!(base.isValid() && other.isValid())) {\n\t return {milliseconds: 0, months: 0};\n\t }\n\t\n\t other = cloneWithOffset(other, base);\n\t if (base.isBefore(other)) {\n\t res = positiveMomentsDifference(base, other);\n\t } else {\n\t res = positiveMomentsDifference(other, base);\n\t res.milliseconds = -res.milliseconds;\n\t res.months = -res.months;\n\t }\n\t\n\t return res;\n\t}\n\t\n\t// TODO: remove 'name' arg after deprecation is removed\n\tfunction createAdder(direction, name) {\n\t return function (val, period) {\n\t var dur, tmp;\n\t //invert the arguments, but complain about it\n\t if (period !== null && !isNaN(+period)) {\n\t deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n\t 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n\t tmp = val; val = period; period = tmp;\n\t }\n\t\n\t val = typeof val === 'string' ? +val : val;\n\t dur = createDuration(val, period);\n\t addSubtract(this, dur, direction);\n\t return this;\n\t };\n\t}\n\t\n\tfunction addSubtract (mom, duration, isAdding, updateOffset) {\n\t var milliseconds = duration._milliseconds,\n\t days = absRound(duration._days),\n\t months = absRound(duration._months);\n\t\n\t if (!mom.isValid()) {\n\t // No op\n\t return;\n\t }\n\t\n\t updateOffset = updateOffset == null ? true : updateOffset;\n\t\n\t if (milliseconds) {\n\t mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n\t }\n\t if (days) {\n\t set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n\t }\n\t if (months) {\n\t setMonth(mom, get(mom, 'Month') + months * isAdding);\n\t }\n\t if (updateOffset) {\n\t hooks.updateOffset(mom, days || months);\n\t }\n\t}\n\t\n\tvar add = createAdder(1, 'add');\n\tvar subtract = createAdder(-1, 'subtract');\n\t\n\tfunction getCalendarFormat(myMoment, now) {\n\t var diff = myMoment.diff(now, 'days', true);\n\t return diff < -6 ? 'sameElse' :\n\t diff < -1 ? 'lastWeek' :\n\t diff < 0 ? 'lastDay' :\n\t diff < 1 ? 'sameDay' :\n\t diff < 2 ? 'nextDay' :\n\t diff < 7 ? 'nextWeek' : 'sameElse';\n\t}\n\t\n\tfunction calendar$1 (time, formats) {\n\t // We want to compare the start of today, vs this.\n\t // Getting start-of-today depends on whether we're local/utc/offset or not.\n\t var now = time || createLocal(),\n\t sod = cloneWithOffset(now, this).startOf('day'),\n\t format = hooks.calendarFormat(this, sod) || 'sameElse';\n\t\n\t var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\t\n\t return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n\t}\n\t\n\tfunction clone () {\n\t return new Moment(this);\n\t}\n\t\n\tfunction isAfter (input, units) {\n\t var localInput = isMoment(input) ? input : createLocal(input);\n\t if (!(this.isValid() && localInput.isValid())) {\n\t return false;\n\t }\n\t units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n\t if (units === 'millisecond') {\n\t return this.valueOf() > localInput.valueOf();\n\t } else {\n\t return localInput.valueOf() < this.clone().startOf(units).valueOf();\n\t }\n\t}\n\t\n\tfunction isBefore (input, units) {\n\t var localInput = isMoment(input) ? input : createLocal(input);\n\t if (!(this.isValid() && localInput.isValid())) {\n\t return false;\n\t }\n\t units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n\t if (units === 'millisecond') {\n\t return this.valueOf() < localInput.valueOf();\n\t } else {\n\t return this.clone().endOf(units).valueOf() < localInput.valueOf();\n\t }\n\t}\n\t\n\tfunction isBetween (from, to, units, inclusivity) {\n\t inclusivity = inclusivity || '()';\n\t return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n\t (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n\t}\n\t\n\tfunction isSame (input, units) {\n\t var localInput = isMoment(input) ? input : createLocal(input),\n\t inputMs;\n\t if (!(this.isValid() && localInput.isValid())) {\n\t return false;\n\t }\n\t units = normalizeUnits(units || 'millisecond');\n\t if (units === 'millisecond') {\n\t return this.valueOf() === localInput.valueOf();\n\t } else {\n\t inputMs = localInput.valueOf();\n\t return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n\t }\n\t}\n\t\n\tfunction isSameOrAfter (input, units) {\n\t return this.isSame(input, units) || this.isAfter(input,units);\n\t}\n\t\n\tfunction isSameOrBefore (input, units) {\n\t return this.isSame(input, units) || this.isBefore(input,units);\n\t}\n\t\n\tfunction diff (input, units, asFloat) {\n\t var that,\n\t zoneDelta,\n\t delta, output;\n\t\n\t if (!this.isValid()) {\n\t return NaN;\n\t }\n\t\n\t that = cloneWithOffset(input, this);\n\t\n\t if (!that.isValid()) {\n\t return NaN;\n\t }\n\t\n\t zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\t\n\t units = normalizeUnits(units);\n\t\n\t if (units === 'year' || units === 'month' || units === 'quarter') {\n\t output = monthDiff(this, that);\n\t if (units === 'quarter') {\n\t output = output / 3;\n\t } else if (units === 'year') {\n\t output = output / 12;\n\t }\n\t } else {\n\t delta = this - that;\n\t output = units === 'second' ? delta / 1e3 : // 1000\n\t units === 'minute' ? delta / 6e4 : // 1000 * 60\n\t units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n\t units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n\t units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n\t delta;\n\t }\n\t return asFloat ? output : absFloor(output);\n\t}\n\t\n\tfunction monthDiff (a, b) {\n\t // difference in months\n\t var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n\t // b is in (anchor - 1 month, anchor + 1 month)\n\t anchor = a.clone().add(wholeMonthDiff, 'months'),\n\t anchor2, adjust;\n\t\n\t if (b - anchor < 0) {\n\t anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n\t // linear across the month\n\t adjust = (b - anchor) / (anchor - anchor2);\n\t } else {\n\t anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n\t // linear across the month\n\t adjust = (b - anchor) / (anchor2 - anchor);\n\t }\n\t\n\t //check for negative zero, return zero if negative zero\n\t return -(wholeMonthDiff + adjust) || 0;\n\t}\n\t\n\thooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n\thooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\t\n\tfunction toString () {\n\t return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n\t}\n\t\n\tfunction toISOString () {\n\t var m = this.clone().utc();\n\t if (0 < m.year() && m.year() <= 9999) {\n\t if (isFunction(Date.prototype.toISOString)) {\n\t // native implementation is ~50x faster, use it when we can\n\t return this.toDate().toISOString();\n\t } else {\n\t return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n\t }\n\t } else {\n\t return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n\t }\n\t}\n\t\n\t/**\n\t * Return a human readable representation of a moment that can\n\t * also be evaluated to get a new moment which is the same\n\t *\n\t * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n\t */\n\tfunction inspect () {\n\t if (!this.isValid()) {\n\t return 'moment.invalid(/* ' + this._i + ' */)';\n\t }\n\t var func = 'moment';\n\t var zone = '';\n\t if (!this.isLocal()) {\n\t func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n\t zone = 'Z';\n\t }\n\t var prefix = '[' + func + '(\"]';\n\t var year = (0 < this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n\t var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n\t var suffix = zone + '[\")]';\n\t\n\t return this.format(prefix + year + datetime + suffix);\n\t}\n\t\n\tfunction format (inputString) {\n\t if (!inputString) {\n\t inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n\t }\n\t var output = formatMoment(this, inputString);\n\t return this.localeData().postformat(output);\n\t}\n\t\n\tfunction from (time, withoutSuffix) {\n\t if (this.isValid() &&\n\t ((isMoment(time) && time.isValid()) ||\n\t createLocal(time).isValid())) {\n\t return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n\t } else {\n\t return this.localeData().invalidDate();\n\t }\n\t}\n\t\n\tfunction fromNow (withoutSuffix) {\n\t return this.from(createLocal(), withoutSuffix);\n\t}\n\t\n\tfunction to (time, withoutSuffix) {\n\t if (this.isValid() &&\n\t ((isMoment(time) && time.isValid()) ||\n\t createLocal(time).isValid())) {\n\t return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n\t } else {\n\t return this.localeData().invalidDate();\n\t }\n\t}\n\t\n\tfunction toNow (withoutSuffix) {\n\t return this.to(createLocal(), withoutSuffix);\n\t}\n\t\n\t// If passed a locale key, it will set the locale for this\n\t// instance. Otherwise, it will return the locale configuration\n\t// variables for this instance.\n\tfunction locale (key) {\n\t var newLocaleData;\n\t\n\t if (key === undefined) {\n\t return this._locale._abbr;\n\t } else {\n\t newLocaleData = getLocale(key);\n\t if (newLocaleData != null) {\n\t this._locale = newLocaleData;\n\t }\n\t return this;\n\t }\n\t}\n\t\n\tvar lang = deprecate(\n\t 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n\t function (key) {\n\t if (key === undefined) {\n\t return this.localeData();\n\t } else {\n\t return this.locale(key);\n\t }\n\t }\n\t);\n\t\n\tfunction localeData () {\n\t return this._locale;\n\t}\n\t\n\tfunction startOf (units) {\n\t units = normalizeUnits(units);\n\t // the following switch intentionally omits break keywords\n\t // to utilize falling through the cases.\n\t switch (units) {\n\t case 'year':\n\t this.month(0);\n\t /* falls through */\n\t case 'quarter':\n\t case 'month':\n\t this.date(1);\n\t /* falls through */\n\t case 'week':\n\t case 'isoWeek':\n\t case 'day':\n\t case 'date':\n\t this.hours(0);\n\t /* falls through */\n\t case 'hour':\n\t this.minutes(0);\n\t /* falls through */\n\t case 'minute':\n\t this.seconds(0);\n\t /* falls through */\n\t case 'second':\n\t this.milliseconds(0);\n\t }\n\t\n\t // weeks are a special case\n\t if (units === 'week') {\n\t this.weekday(0);\n\t }\n\t if (units === 'isoWeek') {\n\t this.isoWeekday(1);\n\t }\n\t\n\t // quarters are also special\n\t if (units === 'quarter') {\n\t this.month(Math.floor(this.month() / 3) * 3);\n\t }\n\t\n\t return this;\n\t}\n\t\n\tfunction endOf (units) {\n\t units = normalizeUnits(units);\n\t if (units === undefined || units === 'millisecond') {\n\t return this;\n\t }\n\t\n\t // 'date' is an alias for 'day', so it should be considered as such.\n\t if (units === 'date') {\n\t units = 'day';\n\t }\n\t\n\t return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n\t}\n\t\n\tfunction valueOf () {\n\t return this._d.valueOf() - ((this._offset || 0) * 60000);\n\t}\n\t\n\tfunction unix () {\n\t return Math.floor(this.valueOf() / 1000);\n\t}\n\t\n\tfunction toDate () {\n\t return new Date(this.valueOf());\n\t}\n\t\n\tfunction toArray () {\n\t var m = this;\n\t return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n\t}\n\t\n\tfunction toObject () {\n\t var m = this;\n\t return {\n\t years: m.year(),\n\t months: m.month(),\n\t date: m.date(),\n\t hours: m.hours(),\n\t minutes: m.minutes(),\n\t seconds: m.seconds(),\n\t milliseconds: m.milliseconds()\n\t };\n\t}\n\t\n\tfunction toJSON () {\n\t // new Date(NaN).toJSON() === null\n\t return this.isValid() ? this.toISOString() : null;\n\t}\n\t\n\tfunction isValid$1 () {\n\t return isValid(this);\n\t}\n\t\n\tfunction parsingFlags () {\n\t return extend({}, getParsingFlags(this));\n\t}\n\t\n\tfunction invalidAt () {\n\t return getParsingFlags(this).overflow;\n\t}\n\t\n\tfunction creationData() {\n\t return {\n\t input: this._i,\n\t format: this._f,\n\t locale: this._locale,\n\t isUTC: this._isUTC,\n\t strict: this._strict\n\t };\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken(0, ['gg', 2], 0, function () {\n\t return this.weekYear() % 100;\n\t});\n\t\n\taddFormatToken(0, ['GG', 2], 0, function () {\n\t return this.isoWeekYear() % 100;\n\t});\n\t\n\tfunction addWeekYearFormatToken (token, getter) {\n\t addFormatToken(0, [token, token.length], 0, getter);\n\t}\n\t\n\taddWeekYearFormatToken('gggg', 'weekYear');\n\taddWeekYearFormatToken('ggggg', 'weekYear');\n\taddWeekYearFormatToken('GGGG', 'isoWeekYear');\n\taddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('weekYear', 'gg');\n\taddUnitAlias('isoWeekYear', 'GG');\n\t\n\t// PRIORITY\n\t\n\taddUnitPriority('weekYear', 1);\n\taddUnitPriority('isoWeekYear', 1);\n\t\n\t\n\t// PARSING\n\t\n\taddRegexToken('G', matchSigned);\n\taddRegexToken('g', matchSigned);\n\taddRegexToken('GG', match1to2, match2);\n\taddRegexToken('gg', match1to2, match2);\n\taddRegexToken('GGGG', match1to4, match4);\n\taddRegexToken('gggg', match1to4, match4);\n\taddRegexToken('GGGGG', match1to6, match6);\n\taddRegexToken('ggggg', match1to6, match6);\n\t\n\taddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n\t week[token.substr(0, 2)] = toInt(input);\n\t});\n\t\n\taddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n\t week[token] = hooks.parseTwoDigitYear(input);\n\t});\n\t\n\t// MOMENTS\n\t\n\tfunction getSetWeekYear (input) {\n\t return getSetWeekYearHelper.call(this,\n\t input,\n\t this.week(),\n\t this.weekday(),\n\t this.localeData()._week.dow,\n\t this.localeData()._week.doy);\n\t}\n\t\n\tfunction getSetISOWeekYear (input) {\n\t return getSetWeekYearHelper.call(this,\n\t input, this.isoWeek(), this.isoWeekday(), 1, 4);\n\t}\n\t\n\tfunction getISOWeeksInYear () {\n\t return weeksInYear(this.year(), 1, 4);\n\t}\n\t\n\tfunction getWeeksInYear () {\n\t var weekInfo = this.localeData()._week;\n\t return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n\t}\n\t\n\tfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n\t var weeksTarget;\n\t if (input == null) {\n\t return weekOfYear(this, dow, doy).year;\n\t } else {\n\t weeksTarget = weeksInYear(input, dow, doy);\n\t if (week > weeksTarget) {\n\t week = weeksTarget;\n\t }\n\t return setWeekAll.call(this, input, week, weekday, dow, doy);\n\t }\n\t}\n\t\n\tfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n\t var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n\t date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\t\n\t this.year(date.getUTCFullYear());\n\t this.month(date.getUTCMonth());\n\t this.date(date.getUTCDate());\n\t return this;\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('Q', 0, 'Qo', 'quarter');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('quarter', 'Q');\n\t\n\t// PRIORITY\n\t\n\taddUnitPriority('quarter', 7);\n\t\n\t// PARSING\n\t\n\taddRegexToken('Q', match1);\n\taddParseToken('Q', function (input, array) {\n\t array[MONTH] = (toInt(input) - 1) * 3;\n\t});\n\t\n\t// MOMENTS\n\t\n\tfunction getSetQuarter (input) {\n\t return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('D', ['DD', 2], 'Do', 'date');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('date', 'D');\n\t\n\t// PRIOROITY\n\taddUnitPriority('date', 9);\n\t\n\t// PARSING\n\t\n\taddRegexToken('D', match1to2);\n\taddRegexToken('DD', match1to2, match2);\n\taddRegexToken('Do', function (isStrict, locale) {\n\t return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;\n\t});\n\t\n\taddParseToken(['D', 'DD'], DATE);\n\taddParseToken('Do', function (input, array) {\n\t array[DATE] = toInt(input.match(match1to2)[0], 10);\n\t});\n\t\n\t// MOMENTS\n\t\n\tvar getSetDayOfMonth = makeGetSet('Date', true);\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('dayOfYear', 'DDD');\n\t\n\t// PRIORITY\n\taddUnitPriority('dayOfYear', 4);\n\t\n\t// PARSING\n\t\n\taddRegexToken('DDD', match1to3);\n\taddRegexToken('DDDD', match3);\n\taddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n\t config._dayOfYear = toInt(input);\n\t});\n\t\n\t// HELPERS\n\t\n\t// MOMENTS\n\t\n\tfunction getSetDayOfYear (input) {\n\t var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n\t return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n\t}\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('m', ['mm', 2], 0, 'minute');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('minute', 'm');\n\t\n\t// PRIORITY\n\t\n\taddUnitPriority('minute', 14);\n\t\n\t// PARSING\n\t\n\taddRegexToken('m', match1to2);\n\taddRegexToken('mm', match1to2, match2);\n\taddParseToken(['m', 'mm'], MINUTE);\n\t\n\t// MOMENTS\n\t\n\tvar getSetMinute = makeGetSet('Minutes', false);\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('s', ['ss', 2], 0, 'second');\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('second', 's');\n\t\n\t// PRIORITY\n\t\n\taddUnitPriority('second', 15);\n\t\n\t// PARSING\n\t\n\taddRegexToken('s', match1to2);\n\taddRegexToken('ss', match1to2, match2);\n\taddParseToken(['s', 'ss'], SECOND);\n\t\n\t// MOMENTS\n\t\n\tvar getSetSecond = makeGetSet('Seconds', false);\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('S', 0, 0, function () {\n\t return ~~(this.millisecond() / 100);\n\t});\n\t\n\taddFormatToken(0, ['SS', 2], 0, function () {\n\t return ~~(this.millisecond() / 10);\n\t});\n\t\n\taddFormatToken(0, ['SSS', 3], 0, 'millisecond');\n\taddFormatToken(0, ['SSSS', 4], 0, function () {\n\t return this.millisecond() * 10;\n\t});\n\taddFormatToken(0, ['SSSSS', 5], 0, function () {\n\t return this.millisecond() * 100;\n\t});\n\taddFormatToken(0, ['SSSSSS', 6], 0, function () {\n\t return this.millisecond() * 1000;\n\t});\n\taddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n\t return this.millisecond() * 10000;\n\t});\n\taddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n\t return this.millisecond() * 100000;\n\t});\n\taddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n\t return this.millisecond() * 1000000;\n\t});\n\t\n\t\n\t// ALIASES\n\t\n\taddUnitAlias('millisecond', 'ms');\n\t\n\t// PRIORITY\n\t\n\taddUnitPriority('millisecond', 16);\n\t\n\t// PARSING\n\t\n\taddRegexToken('S', match1to3, match1);\n\taddRegexToken('SS', match1to3, match2);\n\taddRegexToken('SSS', match1to3, match3);\n\t\n\tvar token;\n\tfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n\t addRegexToken(token, matchUnsigned);\n\t}\n\t\n\tfunction parseMs(input, array) {\n\t array[MILLISECOND] = toInt(('0.' + input) * 1000);\n\t}\n\t\n\tfor (token = 'S'; token.length <= 9; token += 'S') {\n\t addParseToken(token, parseMs);\n\t}\n\t// MOMENTS\n\t\n\tvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('z', 0, 0, 'zoneAbbr');\n\taddFormatToken('zz', 0, 0, 'zoneName');\n\t\n\t// MOMENTS\n\t\n\tfunction getZoneAbbr () {\n\t return this._isUTC ? 'UTC' : '';\n\t}\n\t\n\tfunction getZoneName () {\n\t return this._isUTC ? 'Coordinated Universal Time' : '';\n\t}\n\t\n\tvar proto = Moment.prototype;\n\t\n\tproto.add = add;\n\tproto.calendar = calendar$1;\n\tproto.clone = clone;\n\tproto.diff = diff;\n\tproto.endOf = endOf;\n\tproto.format = format;\n\tproto.from = from;\n\tproto.fromNow = fromNow;\n\tproto.to = to;\n\tproto.toNow = toNow;\n\tproto.get = stringGet;\n\tproto.invalidAt = invalidAt;\n\tproto.isAfter = isAfter;\n\tproto.isBefore = isBefore;\n\tproto.isBetween = isBetween;\n\tproto.isSame = isSame;\n\tproto.isSameOrAfter = isSameOrAfter;\n\tproto.isSameOrBefore = isSameOrBefore;\n\tproto.isValid = isValid$1;\n\tproto.lang = lang;\n\tproto.locale = locale;\n\tproto.localeData = localeData;\n\tproto.max = prototypeMax;\n\tproto.min = prototypeMin;\n\tproto.parsingFlags = parsingFlags;\n\tproto.set = stringSet;\n\tproto.startOf = startOf;\n\tproto.subtract = subtract;\n\tproto.toArray = toArray;\n\tproto.toObject = toObject;\n\tproto.toDate = toDate;\n\tproto.toISOString = toISOString;\n\tproto.inspect = inspect;\n\tproto.toJSON = toJSON;\n\tproto.toString = toString;\n\tproto.unix = unix;\n\tproto.valueOf = valueOf;\n\tproto.creationData = creationData;\n\t\n\t// Year\n\tproto.year = getSetYear;\n\tproto.isLeapYear = getIsLeapYear;\n\t\n\t// Week Year\n\tproto.weekYear = getSetWeekYear;\n\tproto.isoWeekYear = getSetISOWeekYear;\n\t\n\t// Quarter\n\tproto.quarter = proto.quarters = getSetQuarter;\n\t\n\t// Month\n\tproto.month = getSetMonth;\n\tproto.daysInMonth = getDaysInMonth;\n\t\n\t// Week\n\tproto.week = proto.weeks = getSetWeek;\n\tproto.isoWeek = proto.isoWeeks = getSetISOWeek;\n\tproto.weeksInYear = getWeeksInYear;\n\tproto.isoWeeksInYear = getISOWeeksInYear;\n\t\n\t// Day\n\tproto.date = getSetDayOfMonth;\n\tproto.day = proto.days = getSetDayOfWeek;\n\tproto.weekday = getSetLocaleDayOfWeek;\n\tproto.isoWeekday = getSetISODayOfWeek;\n\tproto.dayOfYear = getSetDayOfYear;\n\t\n\t// Hour\n\tproto.hour = proto.hours = getSetHour;\n\t\n\t// Minute\n\tproto.minute = proto.minutes = getSetMinute;\n\t\n\t// Second\n\tproto.second = proto.seconds = getSetSecond;\n\t\n\t// Millisecond\n\tproto.millisecond = proto.milliseconds = getSetMillisecond;\n\t\n\t// Offset\n\tproto.utcOffset = getSetOffset;\n\tproto.utc = setOffsetToUTC;\n\tproto.local = setOffsetToLocal;\n\tproto.parseZone = setOffsetToParsedOffset;\n\tproto.hasAlignedHourOffset = hasAlignedHourOffset;\n\tproto.isDST = isDaylightSavingTime;\n\tproto.isLocal = isLocal;\n\tproto.isUtcOffset = isUtcOffset;\n\tproto.isUtc = isUtc;\n\tproto.isUTC = isUtc;\n\t\n\t// Timezone\n\tproto.zoneAbbr = getZoneAbbr;\n\tproto.zoneName = getZoneName;\n\t\n\t// Deprecations\n\tproto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n\tproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n\tproto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n\tproto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\n\tproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\t\n\tfunction createUnix (input) {\n\t return createLocal(input * 1000);\n\t}\n\t\n\tfunction createInZone () {\n\t return createLocal.apply(null, arguments).parseZone();\n\t}\n\t\n\tfunction preParsePostFormat (string) {\n\t return string;\n\t}\n\t\n\tvar proto$1 = Locale.prototype;\n\t\n\tproto$1.calendar = calendar;\n\tproto$1.longDateFormat = longDateFormat;\n\tproto$1.invalidDate = invalidDate;\n\tproto$1.ordinal = ordinal;\n\tproto$1.preparse = preParsePostFormat;\n\tproto$1.postformat = preParsePostFormat;\n\tproto$1.relativeTime = relativeTime;\n\tproto$1.pastFuture = pastFuture;\n\tproto$1.set = set;\n\t\n\t// Month\n\tproto$1.months = localeMonths;\n\tproto$1.monthsShort = localeMonthsShort;\n\tproto$1.monthsParse = localeMonthsParse;\n\tproto$1.monthsRegex = monthsRegex;\n\tproto$1.monthsShortRegex = monthsShortRegex;\n\t\n\t// Week\n\tproto$1.week = localeWeek;\n\tproto$1.firstDayOfYear = localeFirstDayOfYear;\n\tproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\t\n\t// Day of Week\n\tproto$1.weekdays = localeWeekdays;\n\tproto$1.weekdaysMin = localeWeekdaysMin;\n\tproto$1.weekdaysShort = localeWeekdaysShort;\n\tproto$1.weekdaysParse = localeWeekdaysParse;\n\t\n\tproto$1.weekdaysRegex = weekdaysRegex;\n\tproto$1.weekdaysShortRegex = weekdaysShortRegex;\n\tproto$1.weekdaysMinRegex = weekdaysMinRegex;\n\t\n\t// Hours\n\tproto$1.isPM = localeIsPM;\n\tproto$1.meridiem = localeMeridiem;\n\t\n\tfunction get$1 (format, index, field, setter) {\n\t var locale = getLocale();\n\t var utc = createUTC().set(setter, index);\n\t return locale[field](utc, format);\n\t}\n\t\n\tfunction listMonthsImpl (format, index, field) {\n\t if (isNumber(format)) {\n\t index = format;\n\t format = undefined;\n\t }\n\t\n\t format = format || '';\n\t\n\t if (index != null) {\n\t return get$1(format, index, field, 'month');\n\t }\n\t\n\t var i;\n\t var out = [];\n\t for (i = 0; i < 12; i++) {\n\t out[i] = get$1(format, i, field, 'month');\n\t }\n\t return out;\n\t}\n\t\n\t// ()\n\t// (5)\n\t// (fmt, 5)\n\t// (fmt)\n\t// (true)\n\t// (true, 5)\n\t// (true, fmt, 5)\n\t// (true, fmt)\n\tfunction listWeekdaysImpl (localeSorted, format, index, field) {\n\t if (typeof localeSorted === 'boolean') {\n\t if (isNumber(format)) {\n\t index = format;\n\t format = undefined;\n\t }\n\t\n\t format = format || '';\n\t } else {\n\t format = localeSorted;\n\t index = format;\n\t localeSorted = false;\n\t\n\t if (isNumber(format)) {\n\t index = format;\n\t format = undefined;\n\t }\n\t\n\t format = format || '';\n\t }\n\t\n\t var locale = getLocale(),\n\t shift = localeSorted ? locale._week.dow : 0;\n\t\n\t if (index != null) {\n\t return get$1(format, (index + shift) % 7, field, 'day');\n\t }\n\t\n\t var i;\n\t var out = [];\n\t for (i = 0; i < 7; i++) {\n\t out[i] = get$1(format, (i + shift) % 7, field, 'day');\n\t }\n\t return out;\n\t}\n\t\n\tfunction listMonths (format, index) {\n\t return listMonthsImpl(format, index, 'months');\n\t}\n\t\n\tfunction listMonthsShort (format, index) {\n\t return listMonthsImpl(format, index, 'monthsShort');\n\t}\n\t\n\tfunction listWeekdays (localeSorted, format, index) {\n\t return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n\t}\n\t\n\tfunction listWeekdaysShort (localeSorted, format, index) {\n\t return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n\t}\n\t\n\tfunction listWeekdaysMin (localeSorted, format, index) {\n\t return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n\t}\n\t\n\tgetSetGlobalLocale('en', {\n\t ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n\t ordinal : function (number) {\n\t var b = number % 10,\n\t output = (toInt(number % 100 / 10) === 1) ? 'th' :\n\t (b === 1) ? 'st' :\n\t (b === 2) ? 'nd' :\n\t (b === 3) ? 'rd' : 'th';\n\t return number + output;\n\t }\n\t});\n\t\n\t// Side effect imports\n\thooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\n\thooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\t\n\tvar mathAbs = Math.abs;\n\t\n\tfunction abs () {\n\t var data = this._data;\n\t\n\t this._milliseconds = mathAbs(this._milliseconds);\n\t this._days = mathAbs(this._days);\n\t this._months = mathAbs(this._months);\n\t\n\t data.milliseconds = mathAbs(data.milliseconds);\n\t data.seconds = mathAbs(data.seconds);\n\t data.minutes = mathAbs(data.minutes);\n\t data.hours = mathAbs(data.hours);\n\t data.months = mathAbs(data.months);\n\t data.years = mathAbs(data.years);\n\t\n\t return this;\n\t}\n\t\n\tfunction addSubtract$1 (duration, input, value, direction) {\n\t var other = createDuration(input, value);\n\t\n\t duration._milliseconds += direction * other._milliseconds;\n\t duration._days += direction * other._days;\n\t duration._months += direction * other._months;\n\t\n\t return duration._bubble();\n\t}\n\t\n\t// supports only 2.0-style add(1, 's') or add(duration)\n\tfunction add$1 (input, value) {\n\t return addSubtract$1(this, input, value, 1);\n\t}\n\t\n\t// supports only 2.0-style subtract(1, 's') or subtract(duration)\n\tfunction subtract$1 (input, value) {\n\t return addSubtract$1(this, input, value, -1);\n\t}\n\t\n\tfunction absCeil (number) {\n\t if (number < 0) {\n\t return Math.floor(number);\n\t } else {\n\t return Math.ceil(number);\n\t }\n\t}\n\t\n\tfunction bubble () {\n\t var milliseconds = this._milliseconds;\n\t var days = this._days;\n\t var months = this._months;\n\t var data = this._data;\n\t var seconds, minutes, hours, years, monthsFromDays;\n\t\n\t // if we have a mix of positive and negative values, bubble down first\n\t // check: https://github.com/moment/moment/issues/2166\n\t if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n\t (milliseconds <= 0 && days <= 0 && months <= 0))) {\n\t milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n\t days = 0;\n\t months = 0;\n\t }\n\t\n\t // The following code bubbles up values, see the tests for\n\t // examples of what that means.\n\t data.milliseconds = milliseconds % 1000;\n\t\n\t seconds = absFloor(milliseconds / 1000);\n\t data.seconds = seconds % 60;\n\t\n\t minutes = absFloor(seconds / 60);\n\t data.minutes = minutes % 60;\n\t\n\t hours = absFloor(minutes / 60);\n\t data.hours = hours % 24;\n\t\n\t days += absFloor(hours / 24);\n\t\n\t // convert days to months\n\t monthsFromDays = absFloor(daysToMonths(days));\n\t months += monthsFromDays;\n\t days -= absCeil(monthsToDays(monthsFromDays));\n\t\n\t // 12 months -> 1 year\n\t years = absFloor(months / 12);\n\t months %= 12;\n\t\n\t data.days = days;\n\t data.months = months;\n\t data.years = years;\n\t\n\t return this;\n\t}\n\t\n\tfunction daysToMonths (days) {\n\t // 400 years have 146097 days (taking into account leap year rules)\n\t // 400 years have 12 months === 4800\n\t return days * 4800 / 146097;\n\t}\n\t\n\tfunction monthsToDays (months) {\n\t // the reverse of daysToMonths\n\t return months * 146097 / 4800;\n\t}\n\t\n\tfunction as (units) {\n\t var days;\n\t var months;\n\t var milliseconds = this._milliseconds;\n\t\n\t units = normalizeUnits(units);\n\t\n\t if (units === 'month' || units === 'year') {\n\t days = this._days + milliseconds / 864e5;\n\t months = this._months + daysToMonths(days);\n\t return units === 'month' ? months : months / 12;\n\t } else {\n\t // handle milliseconds separately because of floating point math errors (issue #1867)\n\t days = this._days + Math.round(monthsToDays(this._months));\n\t switch (units) {\n\t case 'week' : return days / 7 + milliseconds / 6048e5;\n\t case 'day' : return days + milliseconds / 864e5;\n\t case 'hour' : return days * 24 + milliseconds / 36e5;\n\t case 'minute' : return days * 1440 + milliseconds / 6e4;\n\t case 'second' : return days * 86400 + milliseconds / 1000;\n\t // Math.floor prevents floating point math errors here\n\t case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n\t default: throw new Error('Unknown unit ' + units);\n\t }\n\t }\n\t}\n\t\n\t// TODO: Use this.as('ms')?\n\tfunction valueOf$1 () {\n\t return (\n\t this._milliseconds +\n\t this._days * 864e5 +\n\t (this._months % 12) * 2592e6 +\n\t toInt(this._months / 12) * 31536e6\n\t );\n\t}\n\t\n\tfunction makeAs (alias) {\n\t return function () {\n\t return this.as(alias);\n\t };\n\t}\n\t\n\tvar asMilliseconds = makeAs('ms');\n\tvar asSeconds = makeAs('s');\n\tvar asMinutes = makeAs('m');\n\tvar asHours = makeAs('h');\n\tvar asDays = makeAs('d');\n\tvar asWeeks = makeAs('w');\n\tvar asMonths = makeAs('M');\n\tvar asYears = makeAs('y');\n\t\n\tfunction get$2 (units) {\n\t units = normalizeUnits(units);\n\t return this[units + 's']();\n\t}\n\t\n\tfunction makeGetter(name) {\n\t return function () {\n\t return this._data[name];\n\t };\n\t}\n\t\n\tvar milliseconds = makeGetter('milliseconds');\n\tvar seconds = makeGetter('seconds');\n\tvar minutes = makeGetter('minutes');\n\tvar hours = makeGetter('hours');\n\tvar days = makeGetter('days');\n\tvar months = makeGetter('months');\n\tvar years = makeGetter('years');\n\t\n\tfunction weeks () {\n\t return absFloor(this.days() / 7);\n\t}\n\t\n\tvar round = Math.round;\n\tvar thresholds = {\n\t s: 45, // seconds to minute\n\t m: 45, // minutes to hour\n\t h: 22, // hours to day\n\t d: 26, // days to month\n\t M: 11 // months to year\n\t};\n\t\n\t// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n\tfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n\t return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n\t}\n\t\n\tfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n\t var duration = createDuration(posNegDuration).abs();\n\t var seconds = round(duration.as('s'));\n\t var minutes = round(duration.as('m'));\n\t var hours = round(duration.as('h'));\n\t var days = round(duration.as('d'));\n\t var months = round(duration.as('M'));\n\t var years = round(duration.as('y'));\n\t\n\t var a = seconds < thresholds.s && ['s', seconds] ||\n\t minutes <= 1 && ['m'] ||\n\t minutes < thresholds.m && ['mm', minutes] ||\n\t hours <= 1 && ['h'] ||\n\t hours < thresholds.h && ['hh', hours] ||\n\t days <= 1 && ['d'] ||\n\t days < thresholds.d && ['dd', days] ||\n\t months <= 1 && ['M'] ||\n\t months < thresholds.M && ['MM', months] ||\n\t years <= 1 && ['y'] || ['yy', years];\n\t\n\t a[2] = withoutSuffix;\n\t a[3] = +posNegDuration > 0;\n\t a[4] = locale;\n\t return substituteTimeAgo.apply(null, a);\n\t}\n\t\n\t// This function allows you to set the rounding function for relative time strings\n\tfunction getSetRelativeTimeRounding (roundingFunction) {\n\t if (roundingFunction === undefined) {\n\t return round;\n\t }\n\t if (typeof(roundingFunction) === 'function') {\n\t round = roundingFunction;\n\t return true;\n\t }\n\t return false;\n\t}\n\t\n\t// This function allows you to set a threshold for relative time strings\n\tfunction getSetRelativeTimeThreshold (threshold, limit) {\n\t if (thresholds[threshold] === undefined) {\n\t return false;\n\t }\n\t if (limit === undefined) {\n\t return thresholds[threshold];\n\t }\n\t thresholds[threshold] = limit;\n\t return true;\n\t}\n\t\n\tfunction humanize (withSuffix) {\n\t var locale = this.localeData();\n\t var output = relativeTime$1(this, !withSuffix, locale);\n\t\n\t if (withSuffix) {\n\t output = locale.pastFuture(+this, output);\n\t }\n\t\n\t return locale.postformat(output);\n\t}\n\t\n\tvar abs$1 = Math.abs;\n\t\n\tfunction toISOString$1() {\n\t // for ISO strings we do not use the normal bubbling rules:\n\t // * milliseconds bubble up until they become hours\n\t // * days do not bubble at all\n\t // * months bubble up until they become years\n\t // This is because there is no context-free conversion between hours and days\n\t // (think of clock changes)\n\t // and also not between days and months (28-31 days per month)\n\t var seconds = abs$1(this._milliseconds) / 1000;\n\t var days = abs$1(this._days);\n\t var months = abs$1(this._months);\n\t var minutes, hours, years;\n\t\n\t // 3600 seconds -> 60 minutes -> 1 hour\n\t minutes = absFloor(seconds / 60);\n\t hours = absFloor(minutes / 60);\n\t seconds %= 60;\n\t minutes %= 60;\n\t\n\t // 12 months -> 1 year\n\t years = absFloor(months / 12);\n\t months %= 12;\n\t\n\t\n\t // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n\t var Y = years;\n\t var M = months;\n\t var D = days;\n\t var h = hours;\n\t var m = minutes;\n\t var s = seconds;\n\t var total = this.asSeconds();\n\t\n\t if (!total) {\n\t // this is the same as C#'s (Noda) and python (isodate)...\n\t // but not other JS (goog.date)\n\t return 'P0D';\n\t }\n\t\n\t return (total < 0 ? '-' : '') +\n\t 'P' +\n\t (Y ? Y + 'Y' : '') +\n\t (M ? M + 'M' : '') +\n\t (D ? D + 'D' : '') +\n\t ((h || m || s) ? 'T' : '') +\n\t (h ? h + 'H' : '') +\n\t (m ? m + 'M' : '') +\n\t (s ? s + 'S' : '');\n\t}\n\t\n\tvar proto$2 = Duration.prototype;\n\t\n\tproto$2.abs = abs;\n\tproto$2.add = add$1;\n\tproto$2.subtract = subtract$1;\n\tproto$2.as = as;\n\tproto$2.asMilliseconds = asMilliseconds;\n\tproto$2.asSeconds = asSeconds;\n\tproto$2.asMinutes = asMinutes;\n\tproto$2.asHours = asHours;\n\tproto$2.asDays = asDays;\n\tproto$2.asWeeks = asWeeks;\n\tproto$2.asMonths = asMonths;\n\tproto$2.asYears = asYears;\n\tproto$2.valueOf = valueOf$1;\n\tproto$2._bubble = bubble;\n\tproto$2.get = get$2;\n\tproto$2.milliseconds = milliseconds;\n\tproto$2.seconds = seconds;\n\tproto$2.minutes = minutes;\n\tproto$2.hours = hours;\n\tproto$2.days = days;\n\tproto$2.weeks = weeks;\n\tproto$2.months = months;\n\tproto$2.years = years;\n\tproto$2.humanize = humanize;\n\tproto$2.toISOString = toISOString$1;\n\tproto$2.toString = toISOString$1;\n\tproto$2.toJSON = toISOString$1;\n\tproto$2.locale = locale;\n\tproto$2.localeData = localeData;\n\t\n\t// Deprecations\n\tproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\n\tproto$2.lang = lang;\n\t\n\t// Side effect imports\n\t\n\t// FORMATTING\n\t\n\taddFormatToken('X', 0, 0, 'unix');\n\taddFormatToken('x', 0, 0, 'valueOf');\n\t\n\t// PARSING\n\t\n\taddRegexToken('x', matchSigned);\n\taddRegexToken('X', matchTimestamp);\n\taddParseToken('X', function (input, array, config) {\n\t config._d = new Date(parseFloat(input, 10) * 1000);\n\t});\n\taddParseToken('x', function (input, array, config) {\n\t config._d = new Date(toInt(input));\n\t});\n\t\n\t// Side effect imports\n\t\n\t\n\thooks.version = '2.17.1';\n\t\n\tsetHookCallback(createLocal);\n\t\n\thooks.fn = proto;\n\thooks.min = min;\n\thooks.max = max;\n\thooks.now = now;\n\thooks.utc = createUTC;\n\thooks.unix = createUnix;\n\thooks.months = listMonths;\n\thooks.isDate = isDate;\n\thooks.locale = getSetGlobalLocale;\n\thooks.invalid = createInvalid;\n\thooks.duration = createDuration;\n\thooks.isMoment = isMoment;\n\thooks.weekdays = listWeekdays;\n\thooks.parseZone = createInZone;\n\thooks.localeData = getLocale;\n\thooks.isDuration = isDuration;\n\thooks.monthsShort = listMonthsShort;\n\thooks.weekdaysMin = listWeekdaysMin;\n\thooks.defineLocale = defineLocale;\n\thooks.updateLocale = updateLocale;\n\thooks.locales = listLocales;\n\thooks.weekdaysShort = listWeekdaysShort;\n\thooks.normalizeUnits = normalizeUnits;\n\thooks.relativeTimeRounding = getSetRelativeTimeRounding;\n\thooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\n\thooks.calendarFormat = getCalendarFormat;\n\thooks.prototype = proto;\n\t\n\treturn hooks;\n\t\n\t})));\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(335)(module)))\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Copyright (c) 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t */\n\t\n\t'use strict';\n\t\n\t/**\n\t * Use invariant() to assert state which your program assumes to be true.\n\t *\n\t * Provide sprintf-style format (only %s is supported) and arguments\n\t * to provide information about what broke and what you were\n\t * expecting.\n\t *\n\t * The invariant message will be stripped in production, but the invariant\n\t * will remain to ensure logic does not differ in production.\n\t */\n\t\n\tvar validateFormat = function validateFormat(format) {};\n\t\n\tif (false) {\n\t validateFormat = function validateFormat(format) {\n\t if (format === undefined) {\n\t throw new Error('invariant requires an error message argument');\n\t }\n\t };\n\t}\n\t\n\tfunction invariant(condition, format, a, b, c, d, e, f) {\n\t validateFormat(format);\n\t\n\t if (!condition) {\n\t var error;\n\t if (format === undefined) {\n\t error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n\t } else {\n\t var args = [a, b, c, d, e, f];\n\t var argIndex = 0;\n\t error = new Error(format.replace(/%s/g, function () {\n\t return args[argIndex++];\n\t }));\n\t error.name = 'Invariant Violation';\n\t }\n\t\n\t error.framesToPop = 1; // we don't care about invariant's own frame\n\t throw error;\n\t }\n\t}\n\t\n\tmodule.exports = invariant;\n\n/***/ },\n/* 3 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Copyright 2014-2015, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t */\n\t\n\t'use strict';\n\t\n\tvar emptyFunction = __webpack_require__(9);\n\t\n\t/**\n\t * Similar to invariant but only logs a warning if the condition is not met.\n\t * This can be used to log issues in development environments in critical\n\t * paths. Removing the logging code for production environments will keep the\n\t * same logic and follow the same code paths.\n\t */\n\t\n\tvar warning = emptyFunction;\n\t\n\tif (false) {\n\t (function () {\n\t var printWarning = function printWarning(format) {\n\t for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n\t args[_key - 1] = arguments[_key];\n\t }\n\t\n\t var argIndex = 0;\n\t var message = 'Warning: ' + format.replace(/%s/g, function () {\n\t return args[argIndex++];\n\t });\n\t if (typeof console !== 'undefined') {\n\t console.error(message);\n\t }\n\t try {\n\t // --- Welcome to debugging React ---\n\t // This error was thrown as a convenience so that you can use this stack\n\t // to find the callsite that caused this warning to fire.\n\t throw new Error(message);\n\t } catch (x) {}\n\t };\n\t\n\t warning = function warning(condition, format) {\n\t if (format === undefined) {\n\t throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');\n\t }\n\t\n\t if (format.indexOf('Failed Composite propType: ') === 0) {\n\t return; // Ignore CompositeComponent proptype check.\n\t }\n\t\n\t if (!condition) {\n\t for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {\n\t args[_key2 - 2] = arguments[_key2];\n\t }\n\t\n\t printWarning.apply(undefined, [format].concat(args));\n\t }\n\t };\n\t })();\n\t}\n\t\n\tmodule.exports = warning;\n\n/***/ },\n/* 4 */\n/***/ function(module, exports) {\n\n\t/**\n\t * Copyright (c) 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t * \n\t */\n\t'use strict';\n\t\n\t/**\n\t * WARNING: DO NOT manually require this module.\n\t * This is a replacement for `invariant(...)` used by the error code system\n\t * and will _only_ be required by the corresponding babel pass.\n\t * It always throws.\n\t */\n\t\n\tfunction reactProdInvariant(code) {\n\t var argCount = arguments.length - 1;\n\t\n\t var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code;\n\t\n\t for (var argIdx = 0; argIdx < argCount; argIdx++) {\n\t message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]);\n\t }\n\t\n\t message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.';\n\t\n\t var error = new Error(message);\n\t error.name = 'Invariant Violation';\n\t error.framesToPop = 1; // we don't care about reactProdInvariant's own frame\n\t\n\t throw error;\n\t}\n\t\n\tmodule.exports = reactProdInvariant;\n\n/***/ },\n/* 5 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t/* eslint-disable no-unused-vars */\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\tvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\t\n\tfunction toObject(val) {\n\t\tif (val === null || val === undefined) {\n\t\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t\t}\n\t\n\t\treturn Object(val);\n\t}\n\t\n\tfunction shouldUseNative() {\n\t\ttry {\n\t\t\tif (!Object.assign) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\t// Detect buggy property enumeration order in older V8 versions.\n\t\n\t\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\t\tvar test1 = new String('abc'); // eslint-disable-line\n\t\t\ttest1[5] = 'de';\n\t\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\t\tvar test2 = {};\n\t\t\tfor (var i = 0; i < 10; i++) {\n\t\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t\t}\n\t\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\t\treturn test2[n];\n\t\t\t});\n\t\t\tif (order2.join('') !== '0123456789') {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\t\tvar test3 = {};\n\t\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\t\ttest3[letter] = letter;\n\t\t\t});\n\t\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\t\treturn false;\n\t\t}\n\t}\n\t\n\tmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\t\tvar from;\n\t\tvar to = toObject(target);\n\t\tvar symbols;\n\t\n\t\tfor (var s = 1; s < arguments.length; s++) {\n\t\t\tfrom = Object(arguments[s]);\n\t\n\t\t\tfor (var key in from) {\n\t\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\t\tto[key] = from[key];\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif (Object.getOwnPropertySymbols) {\n\t\t\t\tsymbols = Object.getOwnPropertySymbols(from);\n\t\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn to;\n\t};\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Copyright 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t */\n\t\n\t'use strict';\n\t\n\tvar _prodInvariant = __webpack_require__(4);\n\t\n\tvar DOMProperty = __webpack_require__(19);\n\tvar ReactDOMComponentFlags = __webpack_require__(175);\n\t\n\tvar invariant = __webpack_require__(2);\n\t\n\tvar ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;\n\tvar Flags = ReactDOMComponentFlags;\n\t\n\tvar internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2);\n\t\n\t/**\n\t * Drill down (through composites and empty components) until we get a host or\n\t * host text component.\n\t *\n\t * This is pretty polymorphic but unavoidable with the current structure we have\n\t * for `_renderedChildren`.\n\t */\n\tfunction getRenderedHostOrTextFromComponent(component) {\n\t var rendered;\n\t while (rendered = component._renderedComponent) {\n\t component = rendered;\n\t }\n\t return component;\n\t}\n\t\n\t/**\n\t * Populate `_hostNode` on the rendered host/text component with the given\n\t * DOM node. The passed `inst` can be a composite.\n\t */\n\tfunction precacheNode(inst, node) {\n\t var hostInst = getRenderedHostOrTextFromComponent(inst);\n\t hostInst._hostNode = node;\n\t node[internalInstanceKey] = hostInst;\n\t}\n\t\n\tfunction uncacheNode(inst) {\n\t var node = inst._hostNode;\n\t if (node) {\n\t delete node[internalInstanceKey];\n\t inst._hostNode = null;\n\t }\n\t}\n\t\n\t/**\n\t * Populate `_hostNode` on each child of `inst`, assuming that the children\n\t * match up with the DOM (element) children of `node`.\n\t *\n\t * We cache entire levels at once to avoid an n^2 problem where we access the\n\t * children of a node sequentially and have to walk from the start to our target\n\t * node every time.\n\t *\n\t * Since we update `_renderedChildren` and the actual DOM at (slightly)\n\t * different times, we could race here and see a newer `_renderedChildren` than\n\t * the DOM nodes we see. To avoid this, ReactMultiChild calls\n\t * `prepareToManageChildren` before we change `_renderedChildren`, at which\n\t * time the container's child nodes are always cached (until it unmounts).\n\t */\n\tfunction precacheChildNodes(inst, node) {\n\t if (inst._flags & Flags.hasCachedChildNodes) {\n\t return;\n\t }\n\t var children = inst._renderedChildren;\n\t var childNode = node.firstChild;\n\t outer: for (var name in children) {\n\t if (!children.hasOwnProperty(name)) {\n\t continue;\n\t }\n\t var childInst = children[name];\n\t var childID = getRenderedHostOrTextFromComponent(childInst)._domID;\n\t if (childID === 0) {\n\t // We're currently unmounting this child in ReactMultiChild; skip it.\n\t continue;\n\t }\n\t // We assume the child nodes are in the same order as the child instances.\n\t for (; childNode !== null; childNode = childNode.nextSibling) {\n\t if (childNode.nodeType === 1 && childNode.getAttribute(ATTR_NAME) === String(childID) || childNode.nodeType === 8 && childNode.nodeValue === ' react-text: ' + childID + ' ' || childNode.nodeType === 8 && childNode.nodeValue === ' react-empty: ' + childID + ' ') {\n\t precacheNode(childInst, childNode);\n\t continue outer;\n\t }\n\t }\n\t // We reached the end of the DOM children without finding an ID match.\n\t true ? false ? invariant(false, 'Unable to find element with ID %s.', childID) : _prodInvariant('32', childID) : void 0;\n\t }\n\t inst._flags |= Flags.hasCachedChildNodes;\n\t}\n\t\n\t/**\n\t * Given a DOM node, return the closest ReactDOMComponent or\n\t * ReactDOMTextComponent instance ancestor.\n\t */\n\tfunction getClosestInstanceFromNode(node) {\n\t if (node[internalInstanceKey]) {\n\t return node[internalInstanceKey];\n\t }\n\t\n\t // Walk up the tree until we find an ancestor whose instance we have cached.\n\t var parents = [];\n\t while (!node[internalInstanceKey]) {\n\t parents.push(node);\n\t if (node.parentNode) {\n\t node = node.parentNode;\n\t } else {\n\t // Top of the tree. This node must not be part of a React tree (or is\n\t // unmounted, potentially).\n\t return null;\n\t }\n\t }\n\t\n\t var closest;\n\t var inst;\n\t for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) {\n\t closest = inst;\n\t if (parents.length) {\n\t precacheChildNodes(inst, node);\n\t }\n\t }\n\t\n\t return closest;\n\t}\n\t\n\t/**\n\t * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent\n\t * instance, or null if the node was not rendered by this React.\n\t */\n\tfunction getInstanceFromNode(node) {\n\t var inst = getClosestInstanceFromNode(node);\n\t if (inst != null && inst._hostNode === node) {\n\t return inst;\n\t } else {\n\t return null;\n\t }\n\t}\n\t\n\t/**\n\t * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding\n\t * DOM node.\n\t */\n\tfunction getNodeFromInstance(inst) {\n\t // Without this first invariant, passing a non-DOM-component triggers the next\n\t // invariant for a missing parent, which is super confusing.\n\t !(inst._hostNode !== undefined) ? false ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;\n\t\n\t if (inst._hostNode) {\n\t return inst._hostNode;\n\t }\n\t\n\t // Walk up the tree until we find an ancestor whose DOM node we have cached.\n\t var parents = [];\n\t while (!inst._hostNode) {\n\t parents.push(inst);\n\t !inst._hostParent ? false ? invariant(false, 'React DOM tree root should always have a node reference.') : _prodInvariant('34') : void 0;\n\t inst = inst._hostParent;\n\t }\n\t\n\t // Now parents contains each ancestor that does *not* have a cached native\n\t // node, and `inst` is the deepest ancestor that does.\n\t for (; parents.length; inst = parents.pop()) {\n\t precacheChildNodes(inst, inst._hostNode);\n\t }\n\t\n\t return inst._hostNode;\n\t}\n\t\n\tvar ReactDOMComponentTree = {\n\t getClosestInstanceFromNode: getClosestInstanceFromNode,\n\t getInstanceFromNode: getInstanceFromNode,\n\t getNodeFromInstance: getNodeFromInstance,\n\t precacheChildNodes: precacheChildNodes,\n\t precacheNode: precacheNode,\n\t uncacheNode: uncacheNode\n\t};\n\t\n\tmodule.exports = ReactDOMComponentTree;\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\t/**\n\t * Copyright (c) 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t */\n\t\n\t'use strict';\n\t\n\tvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n\t\n\t/**\n\t * Simple, lightweight module assisting with the detection and context of\n\t * Worker. Helps avoid circular dependencies and allows code to reason about\n\t * whether or not they are in a Worker, even if they never include the main\n\t * `ReactWorker` dependency.\n\t */\n\tvar ExecutionEnvironment = {\n\t\n\t canUseDOM: canUseDOM,\n\t\n\t canUseWorkers: typeof Worker !== 'undefined',\n\t\n\t canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),\n\t\n\t canUseViewport: canUseDOM && !!window.screen,\n\t\n\t isInWorker: !canUseDOM // For now, this is true - might change in the future.\n\t\n\t};\n\t\n\tmodule.exports = ExecutionEnvironment;\n\n/***/ },\n/* 8 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar bind = __webpack_require__(59);\n\t\n\t/*global toString:true*/\n\t\n\t// utils is a library of generic helper functions non-specific to axios\n\t\n\tvar toString = Object.prototype.toString;\n\t\n\t/**\n\t * Determine if a value is an Array\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Array, otherwise false\n\t */\n\tfunction isArray(val) {\n\t return toString.call(val) === '[object Array]';\n\t}\n\t\n\t/**\n\t * Determine if a value is an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBuffer(val) {\n\t return toString.call(val) === '[object ArrayBuffer]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a FormData\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an FormData, otherwise false\n\t */\n\tfunction isFormData(val) {\n\t return (typeof FormData !== 'undefined') && (val instanceof FormData);\n\t}\n\t\n\t/**\n\t * Determine if a value is a view on an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBufferView(val) {\n\t var result;\n\t if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n\t result = ArrayBuffer.isView(val);\n\t } else {\n\t result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Determine if a value is a String\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a String, otherwise false\n\t */\n\tfunction isString(val) {\n\t return typeof val === 'string';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Number\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Number, otherwise false\n\t */\n\tfunction isNumber(val) {\n\t return typeof val === 'number';\n\t}\n\t\n\t/**\n\t * Determine if a value is undefined\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if the value is undefined, otherwise false\n\t */\n\tfunction isUndefined(val) {\n\t return typeof val === 'undefined';\n\t}\n\t\n\t/**\n\t * Determine if a value is an Object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Object, otherwise false\n\t */\n\tfunction isObject(val) {\n\t return val !== null && typeof val === 'object';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Date\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Date, otherwise false\n\t */\n\tfunction isDate(val) {\n\t return toString.call(val) === '[object Date]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a File\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a File, otherwise false\n\t */\n\tfunction isFile(val) {\n\t return toString.call(val) === '[object File]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Blob\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Blob, otherwise false\n\t */\n\tfunction isBlob(val) {\n\t return toString.call(val) === '[object Blob]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Function\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Function, otherwise false\n\t */\n\tfunction isFunction(val) {\n\t return toString.call(val) === '[object Function]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Stream\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Stream, otherwise false\n\t */\n\tfunction isStream(val) {\n\t return isObject(val) && isFunction(val.pipe);\n\t}\n\t\n\t/**\n\t * Determine if a value is a URLSearchParams object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n\t */\n\tfunction isURLSearchParams(val) {\n\t return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;\n\t}\n\t\n\t/**\n\t * Trim excess whitespace off the beginning and end of a string\n\t *\n\t * @param {String} str The String to trim\n\t * @returns {String} The String freed of excess whitespace\n\t */\n\tfunction trim(str) {\n\t return str.replace(/^\\s*/, '').replace(/\\s*$/, '');\n\t}\n\t\n\t/**\n\t * Determine if we're running in a standard browser environment\n\t *\n\t * This allows axios to run in a web worker, and react-native.\n\t * Both environments support XMLHttpRequest, but not fully standard globals.\n\t *\n\t * web workers:\n\t * typeof window -> undefined\n\t * typeof document -> undefined\n\t *\n\t * react-native:\n\t * typeof document.createElement -> undefined\n\t */\n\tfunction isStandardBrowserEnv() {\n\t return (\n\t typeof window !== 'undefined' &&\n\t typeof document !== 'undefined' &&\n\t typeof document.createElement === 'function'\n\t );\n\t}\n\t\n\t/**\n\t * Iterate over an Array or an Object invoking a function for each item.\n\t *\n\t * If `obj` is an Array callback will be called passing\n\t * the value, index, and complete array for each item.\n\t *\n\t * If 'obj' is an Object callback will be called passing\n\t * the value, key, and complete object for each property.\n\t *\n\t * @param {Object|Array} obj The object to iterate\n\t * @param {Function} fn The callback to invoke for each item\n\t */\n\tfunction forEach(obj, fn) {\n\t // Don't bother if no value provided\n\t if (obj === null || typeof obj === 'undefined') {\n\t return;\n\t }\n\t\n\t // Force an array if not already something iterable\n\t if (typeof obj !== 'object' && !isArray(obj)) {\n\t /*eslint no-param-reassign:0*/\n\t obj = [obj];\n\t }\n\t\n\t if (isArray(obj)) {\n\t // Iterate over array values\n\t for (var i = 0, l = obj.length; i < l; i++) {\n\t fn.call(null, obj[i], i, obj);\n\t }\n\t } else {\n\t // Iterate over object keys\n\t for (var key in obj) {\n\t if (Object.prototype.hasOwnProperty.call(obj, key)) {\n\t fn.call(null, obj[key], key, obj);\n\t }\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * Accepts varargs expecting each argument to be an object, then\n\t * immutably merges the properties of each object and returns result.\n\t *\n\t * When multiple objects contain the same key the later object in\n\t * the arguments list will take precedence.\n\t *\n\t * Example:\n\t *\n\t * ```js\n\t * var result = merge({foo: 123}, {foo: 456});\n\t * console.log(result.foo); // outputs 456\n\t * ```\n\t *\n\t * @param {Object} obj1 Object to merge\n\t * @returns {Object} Result of all merge properties\n\t */\n\tfunction merge(/* obj1, obj2, obj3, ... */) {\n\t var result = {};\n\t function assignValue(val, key) {\n\t if (typeof result[key] === 'object' && typeof val === 'object') {\n\t result[key] = merge(result[key], val);\n\t } else {\n\t result[key] = val;\n\t }\n\t }\n\t\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t forEach(arguments[i], assignValue);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Extends object a by mutably adding to it the properties of object b.\n\t *\n\t * @param {Object} a The object to be extended\n\t * @param {Object} b The object to copy properties from\n\t * @param {Object} thisArg The object to bind function to\n\t * @return {Object} The resulting value of object a\n\t */\n\tfunction extend(a, b, thisArg) {\n\t forEach(b, function assignValue(val, key) {\n\t if (thisArg && typeof val === 'function') {\n\t a[key] = bind(val, thisArg);\n\t } else {\n\t a[key] = val;\n\t }\n\t });\n\t return a;\n\t}\n\t\n\tmodule.exports = {\n\t isArray: isArray,\n\t isArrayBuffer: isArrayBuffer,\n\t isFormData: isFormData,\n\t isArrayBufferView: isArrayBufferView,\n\t isString: isString,\n\t isNumber: isNumber,\n\t isObject: isObject,\n\t isUndefined: isUndefined,\n\t isDate: isDate,\n\t isFile: isFile,\n\t isBlob: isBlob,\n\t isFunction: isFunction,\n\t isStream: isStream,\n\t isURLSearchParams: isURLSearchParams,\n\t isStandardBrowserEnv: isStandardBrowserEnv,\n\t forEach: forEach,\n\t merge: merge,\n\t extend: extend,\n\t trim: trim\n\t};\n\n\n/***/ },\n/* 9 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t\n\t/**\n\t * Copyright (c) 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t * \n\t */\n\t\n\tfunction makeEmptyFunction(arg) {\n\t return function () {\n\t return arg;\n\t };\n\t}\n\t\n\t/**\n\t * This function accepts and discards inputs; it has no side effects. This is\n\t * primarily useful idiomatically for overridable function endpoints which\n\t * always need to be callable, since JS lacks a null-call idiom ala Cocoa.\n\t */\n\tvar emptyFunction = function emptyFunction() {};\n\t\n\temptyFunction.thatReturns = makeEmptyFunction;\n\temptyFunction.thatReturnsFalse = makeEmptyFunction(false);\n\temptyFunction.thatReturnsTrue = makeEmptyFunction(true);\n\temptyFunction.thatReturnsNull = makeEmptyFunction(null);\n\temptyFunction.thatReturnsThis = function () {\n\t return this;\n\t};\n\temptyFunction.thatReturnsArgument = function (arg) {\n\t return arg;\n\t};\n\t\n\tmodule.exports = emptyFunction;\n\n/***/ },\n/* 10 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Copyright 2016-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t * \n\t */\n\t\n\t'use strict';\n\t\n\t// Trust the developer to only use ReactInstrumentation with a __DEV__ check\n\t\n\tvar debugTool = null;\n\t\n\tif (false) {\n\t var ReactDebugTool = require('./ReactDebugTool');\n\t debugTool = ReactDebugTool;\n\t}\n\t\n\tmodule.exports = { debugTool: debugTool };\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Copyright 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t */\n\t\n\t'use strict';\n\t\n\tvar _prodInvariant = __webpack_require__(4),\n\t _assign = __webpack_require__(5);\n\t\n\tvar CallbackQueue = __webpack_require__(173);\n\tvar PooledClass = __webpack_require__(17);\n\tvar ReactFeatureFlags = __webpack_require__(178);\n\tvar ReactReconciler = __webpack_require__(20);\n\tvar Transaction = __webpack_require__(31);\n\t\n\tvar invariant = __webpack_require__(2);\n\t\n\tvar dirtyComponents = [];\n\tvar updateBatchNumber = 0;\n\tvar asapCallbackQueue = CallbackQueue.getPooled();\n\tvar asapEnqueued = false;\n\t\n\tvar batchingStrategy = null;\n\t\n\tfunction ensureInjected() {\n\t !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? false ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : _prodInvariant('123') : void 0;\n\t}\n\t\n\tvar NESTED_UPDATES = {\n\t initialize: function () {\n\t this.dirtyComponentsLength = dirtyComponents.length;\n\t },\n\t close: function () {\n\t if (this.dirtyComponentsLength !== dirtyComponents.length) {\n\t // Additional updates were enqueued by componentDidUpdate handlers or\n\t // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run\n\t // these new updates so that if A's componentDidUpdate calls setState on\n\t // B, B will update before the callback A's updater provided when calling\n\t // setState.\n\t dirtyComponents.splice(0, this.dirtyComponentsLength);\n\t flushBatchedUpdates();\n\t } else {\n\t dirtyComponents.length = 0;\n\t }\n\t }\n\t};\n\t\n\tvar UPDATE_QUEUEING = {\n\t initialize: function () {\n\t this.callbackQueue.reset();\n\t },\n\t close: function () {\n\t this.callbackQueue.notifyAll();\n\t }\n\t};\n\t\n\tvar TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];\n\t\n\tfunction ReactUpdatesFlushTransaction() {\n\t this.reinitializeTransaction();\n\t this.dirtyComponentsLength = null;\n\t this.callbackQueue = CallbackQueue.getPooled();\n\t this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled(\n\t /* useCreateElement */true);\n\t}\n\t\n\t_assign(ReactUpdatesFlushTransaction.prototype, Transaction, {\n\t getTransactionWrappers: function () {\n\t return TRANSACTION_WRAPPERS;\n\t },\n\t\n\t destructor: function () {\n\t this.dirtyComponentsLength = null;\n\t CallbackQueue.release(this.callbackQueue);\n\t this.callbackQueue = null;\n\t ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);\n\t this.reconcileTransaction = null;\n\t },\n\t\n\t perform: function (method, scope, a) {\n\t // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`\n\t // with this transaction's wrappers around it.\n\t return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a);\n\t }\n\t});\n\t\n\tPooledClass.addPoolingTo(ReactUpdatesFlushTransaction);\n\t\n\tfunction batchedUpdates(callback, a, b, c, d, e) {\n\t ensureInjected();\n\t return batchingStrategy.batchedUpdates(callback, a, b, c, d, e);\n\t}\n\t\n\t/**\n\t * Array comparator for ReactComponents by mount ordering.\n\t *\n\t * @param {ReactComponent} c1 first component you're comparing\n\t * @param {ReactComponent} c2 second component you're comparing\n\t * @return {number} Return value usable by Array.prototype.sort().\n\t */\n\tfunction mountOrderComparator(c1, c2) {\n\t return c1._mountOrder - c2._mountOrder;\n\t}\n\t\n\tfunction runBatchedUpdates(transaction) {\n\t var len = transaction.dirtyComponentsLength;\n\t !(len === dirtyComponents.length) ? false ? invariant(false, 'Expected flush transaction\\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : _prodInvariant('124', len, dirtyComponents.length) : void 0;\n\t\n\t // Since reconciling a component higher in the owner hierarchy usually (not\n\t // always -- see shouldComponentUpdate()) will reconcile children, reconcile\n\t // them before their children by sorting the array.\n\t dirtyComponents.sort(mountOrderComparator);\n\t\n\t // Any updates enqueued while reconciling must be performed after this entire\n\t // batch. Otherwise, if dirtyComponents is [A, B] where A has children B and\n\t // C, B could update twice in a single batch if C's render enqueues an update\n\t // to B (since B would have already updated, we should skip it, and the only\n\t // way we can know to do so is by checking the batch counter).\n\t updateBatchNumber++;\n\t\n\t for (var i = 0; i < len; i++) {\n\t // If a component is unmounted before pending changes apply, it will still\n\t // be here, but we assume that it has cleared its _pendingCallbacks and\n\t // that performUpdateIfNecessary is a noop.\n\t var component = dirtyComponents[i];\n\t\n\t // If performUpdateIfNecessary happens to enqueue any new updates, we\n\t // shouldn't execute the callbacks until the next render happens, so\n\t // stash the callbacks first\n\t var callbacks = component._pendingCallbacks;\n\t component._pendingCallbacks = null;\n\t\n\t var markerName;\n\t if (ReactFeatureFlags.logTopLevelRenders) {\n\t var namedComponent = component;\n\t // Duck type TopLevelWrapper. This is probably always true.\n\t if (component._currentElement.type.isReactTopLevelWrapper) {\n\t namedComponent = component._renderedComponent;\n\t }\n\t markerName = 'React update: ' + namedComponent.getName();\n\t console.time(markerName);\n\t }\n\t\n\t ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber);\n\t\n\t if (markerName) {\n\t console.timeEnd(markerName);\n\t }\n\t\n\t if (callbacks) {\n\t for (var j = 0; j < callbacks.length; j++) {\n\t transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance());\n\t }\n\t }\n\t }\n\t}\n\t\n\tvar flushBatchedUpdates = function () {\n\t // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents\n\t // array and perform any updates enqueued by mount-ready handlers (i.e.,\n\t // componentDidUpdate) but we need to check here too in order to catch\n\t // updates enqueued by setState callbacks and asap calls.\n\t while (dirtyComponents.length || asapEnqueued) {\n\t if (dirtyComponents.length) {\n\t var transaction = ReactUpdatesFlushTransaction.getPooled();\n\t transaction.perform(runBatchedUpdates, null, transaction);\n\t ReactUpdatesFlushTransaction.release(transaction);\n\t }\n\t\n\t if (asapEnqueued) {\n\t asapEnqueued = false;\n\t var queue = asapCallbackQueue;\n\t asapCallbackQueue = CallbackQueue.getPooled();\n\t queue.notifyAll();\n\t CallbackQueue.release(queue);\n\t }\n\t }\n\t};\n\t\n\t/**\n\t * Mark a component as needing a rerender, adding an optional callback to a\n\t * list of functions which will be executed once the rerender occurs.\n\t */\n\tfunction enqueueUpdate(component) {\n\t ensureInjected();\n\t\n\t // Various parts of our code (such as ReactCompositeComponent's\n\t // _renderValidatedComponent) assume that calls to render aren't nested;\n\t // verify that that's the case. (This is called by each top-level update\n\t // function, like setState, forceUpdate, etc.; creation and\n\t // destruction of top-level components is guarded in ReactMount.)\n\t\n\t if (!batchingStrategy.isBatchingUpdates) {\n\t batchingStrategy.batchedUpdates(enqueueUpdate, component);\n\t return;\n\t }\n\t\n\t dirtyComponents.push(component);\n\t if (component._updateBatchNumber == null) {\n\t component._updateBatchNumber = updateBatchNumber + 1;\n\t }\n\t}\n\t\n\t/**\n\t * Enqueue a callback to be run at the end of the current batching cycle. Throws\n\t * if no updates are currently being performed.\n\t */\n\tfunction asap(callback, context) {\n\t !batchingStrategy.isBatchingUpdates ? false ? invariant(false, 'ReactUpdates.asap: Can\\'t enqueue an asap callback in a context whereupdates are not being batched.') : _prodInvariant('125') : void 0;\n\t asapCallbackQueue.enqueue(callback, context);\n\t asapEnqueued = true;\n\t}\n\t\n\tvar ReactUpdatesInjection = {\n\t injectReconcileTransaction: function (ReconcileTransaction) {\n\t !ReconcileTransaction ? false ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : _prodInvariant('126') : void 0;\n\t ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;\n\t },\n\t\n\t injectBatchingStrategy: function (_batchingStrategy) {\n\t !_batchingStrategy ? false ? invariant(false, 'ReactUpdates: must provide a batching strategy') : _prodInvariant('127') : void 0;\n\t !(typeof _batchingStrategy.batchedUpdates === 'function') ? false ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : _prodInvariant('128') : void 0;\n\t !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? false ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : _prodInvariant('129') : void 0;\n\t batchingStrategy = _batchingStrategy;\n\t }\n\t};\n\t\n\tvar ReactUpdates = {\n\t /**\n\t * React references `ReactReconcileTransaction` using this property in order\n\t * to allow dependency injection.\n\t *\n\t * @internal\n\t */\n\t ReactReconcileTransaction: null,\n\t\n\t batchedUpdates: batchedUpdates,\n\t enqueueUpdate: enqueueUpdate,\n\t flushBatchedUpdates: flushBatchedUpdates,\n\t injection: ReactUpdatesInjection,\n\t asap: asap\n\t};\n\t\n\tmodule.exports = ReactUpdates;\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Copyright 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t */\n\t\n\t'use strict';\n\t\n\tvar _assign = __webpack_require__(5);\n\t\n\tvar PooledClass = __webpack_require__(17);\n\t\n\tvar emptyFunction = __webpack_require__(9);\n\tvar warning = __webpack_require__(3);\n\t\n\tvar didWarnForAddedNewProperty = false;\n\tvar isProxySupported = typeof Proxy === 'function';\n\t\n\tvar shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];\n\t\n\t/**\n\t * @interface Event\n\t * @see http://www.w3.org/TR/DOM-Level-3-Events/\n\t */\n\tvar EventInterface = {\n\t type: null,\n\t target: null,\n\t // currentTarget is set when dispatching; no use in copying it here\n\t currentTarget: emptyFunction.thatReturnsNull,\n\t eventPhase: null,\n\t bubbles: null,\n\t cancelable: null,\n\t timeStamp: function (event) {\n\t return event.timeStamp || Date.now();\n\t },\n\t defaultPrevented: null,\n\t isTrusted: null\n\t};\n\t\n\t/**\n\t * Synthetic events are dispatched by event plugins, typically in response to a\n\t * top-level event delegation handler.\n\t *\n\t * These systems should generally use pooling to reduce the frequency of garbage\n\t * collection. The system should check `isPersistent` to determine whether the\n\t * event should be released into the pool after being dispatched. Users that\n\t * need a persisted event should invoke `persist`.\n\t *\n\t * Synthetic events (and subclasses) implement the DOM Level 3 Events API by\n\t * normalizing browser quirks. Subclasses do not necessarily have to implement a\n\t * DOM interface; custom application-specific events can also subclass this.\n\t *\n\t * @param {object} dispatchConfig Configuration used to dispatch this event.\n\t * @param {*} targetInst Marker identifying the event target.\n\t * @param {object} nativeEvent Native browser event.\n\t * @param {DOMEventTarget} nativeEventTarget Target node.\n\t */\n\tfunction SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {\n\t if (false) {\n\t // these have a getter/setter for warnings\n\t delete this.nativeEvent;\n\t delete this.preventDefault;\n\t delete this.stopPropagation;\n\t }\n\t\n\t this.dispatchConfig = dispatchConfig;\n\t this._targetInst = targetInst;\n\t this.nativeEvent = nativeEvent;\n\t\n\t var Interface = this.constructor.Interface;\n\t for (var propName in Interface) {\n\t if (!Interface.hasOwnProperty(propName)) {\n\t continue;\n\t }\n\t if (false) {\n\t delete this[propName]; // this has a getter/setter for warnings\n\t }\n\t var normalize = Interface[propName];\n\t if (normalize) {\n\t this[propName] = normalize(nativeEvent);\n\t } else {\n\t if (propName === 'target') {\n\t this.target = nativeEventTarget;\n\t } else {\n\t this[propName] = nativeEvent[propName];\n\t }\n\t }\n\t }\n\t\n\t var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;\n\t if (defaultPrevented) {\n\t this.isDefaultPrevented = emptyFunction.thatReturnsTrue;\n\t } else {\n\t this.isDefaultPrevented = emptyFunction.thatReturnsFalse;\n\t }\n\t this.isPropagationStopped = emptyFunction.thatReturnsFalse;\n\t return this;\n\t}\n\t\n\t_assign(SyntheticEvent.prototype, {\n\t\n\t preventDefault: function () {\n\t this.defaultPrevented = true;\n\t var event = this.nativeEvent;\n\t if (!event) {\n\t return;\n\t }\n\t\n\t if (event.preventDefault) {\n\t event.preventDefault();\n\t } else if (typeof event.returnValue !== 'unknown') {\n\t // eslint-disable-line valid-typeof\n\t event.returnValue = false;\n\t }\n\t this.isDefaultPrevented = emptyFunction.thatReturnsTrue;\n\t },\n\t\n\t stopPropagation: function () {\n\t var event = this.nativeEvent;\n\t if (!event) {\n\t return;\n\t }\n\t\n\t if (event.stopPropagation) {\n\t event.stopPropagation();\n\t } else if (typeof event.cancelBubble !== 'unknown') {\n\t // eslint-disable-line valid-typeof\n\t // The ChangeEventPlugin registers a \"propertychange\" event for\n\t // IE. This event does not support bubbling or cancelling, and\n\t // any references to cancelBubble throw \"Member not found\". A\n\t // typeof check of \"unknown\" circumvents this issue (and is also\n\t // IE specific).\n\t event.cancelBubble = true;\n\t }\n\t\n\t this.isPropagationStopped = emptyFunction.thatReturnsTrue;\n\t },\n\t\n\t /**\n\t * We release all dispatched `SyntheticEvent`s after each event loop, adding\n\t * them back into the pool. This allows a way to hold onto a reference that\n\t * won't be added back into the pool.\n\t */\n\t persist: function () {\n\t this.isPersistent = emptyFunction.thatReturnsTrue;\n\t },\n\t\n\t /**\n\t * Checks if this event should be released back into the pool.\n\t *\n\t * @return {boolean} True if this should not be released, false otherwise.\n\t */\n\t isPersistent: emptyFunction.thatReturnsFalse,\n\t\n\t /**\n\t * `PooledClass` looks for `destructor` on each instance it releases.\n\t */\n\t destructor: function () {\n\t var Interface = this.constructor.Interface;\n\t for (var propName in Interface) {\n\t if (false) {\n\t Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));\n\t } else {\n\t this[propName] = null;\n\t }\n\t }\n\t for (var i = 0; i < shouldBeReleasedProperties.length; i++) {\n\t this[shouldBeReleasedProperties[i]] = null;\n\t }\n\t if (false) {\n\t Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));\n\t Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction));\n\t Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction));\n\t }\n\t }\n\t\n\t});\n\t\n\tSyntheticEvent.Interface = EventInterface;\n\t\n\tif (false) {\n\t if (isProxySupported) {\n\t /*eslint-disable no-func-assign */\n\t SyntheticEvent = new Proxy(SyntheticEvent, {\n\t construct: function (target, args) {\n\t return this.apply(target, Object.create(target.prototype), args);\n\t },\n\t apply: function (constructor, that, args) {\n\t return new Proxy(constructor.apply(that, args), {\n\t set: function (target, prop, value) {\n\t if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {\n\t process.env.NODE_ENV !== 'production' ? warning(didWarnForAddedNewProperty || target.isPersistent(), 'This synthetic event is reused for performance reasons. If you\\'re ' + 'seeing this, you\\'re adding a new property in the synthetic event object. ' + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0;\n\t didWarnForAddedNewProperty = true;\n\t }\n\t target[prop] = value;\n\t return true;\n\t }\n\t });\n\t }\n\t });\n\t /*eslint-enable no-func-assign */\n\t }\n\t}\n\t/**\n\t * Helper to reduce boilerplate when creating subclasses.\n\t *\n\t * @param {function} Class\n\t * @param {?object} Interface\n\t */\n\tSyntheticEvent.augmentClass = function (Class, Interface) {\n\t var Super = this;\n\t\n\t var E = function () {};\n\t E.prototype = Super.prototype;\n\t var prototype = new E();\n\t\n\t _assign(prototype, Class.prototype);\n\t Class.prototype = prototype;\n\t Class.prototype.constructor = Class;\n\t\n\t Class.Interface = _assign({}, Super.Interface, Interface);\n\t Class.augmentClass = Super.augmentClass;\n\t\n\t PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler);\n\t};\n\t\n\tPooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler);\n\t\n\tmodule.exports = SyntheticEvent;\n\t\n\t/**\n\t * Helper to nullify syntheticEvent instance properties when destructing\n\t *\n\t * @param {object} SyntheticEvent\n\t * @param {String} propName\n\t * @return {object} defineProperty object\n\t */\n\tfunction getPooledWarningPropertyDefinition(propName, getVal) {\n\t var isFunction = typeof getVal === 'function';\n\t return {\n\t configurable: true,\n\t set: set,\n\t get: get\n\t };\n\t\n\t function set(val) {\n\t var action = isFunction ? 'setting the method' : 'setting the property';\n\t warn(action, 'This is effectively a no-op');\n\t return val;\n\t }\n\t\n\t function get() {\n\t var action = isFunction ? 'accessing the method' : 'accessing the property';\n\t var result = isFunction ? 'This is a no-op function' : 'This is set to null';\n\t warn(action, result);\n\t return getVal;\n\t }\n\t\n\t function warn(action, result) {\n\t var warningCondition = false;\n\t false ? warning(warningCondition, 'This synthetic event is reused for performance reasons. If you\\'re seeing this, ' + 'you\\'re %s `%s` on a released/nullified synthetic event. %s. ' + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;\n\t }\n\t}\n\n/***/ },\n/* 13 */\n/***/ function(module, exports) {\n\n\t/**\n\t * Copyright 2013-present, Facebook, Inc.\n\t * All rights reserved.\n\t *\n\t * This source code is licensed under the BSD-style license found in the\n\t * LICENSE file in the root directory of this source tree. An additional grant\n\t * of patent rights can be found in the PATENTS file in the same directory.\n\t *\n\t * \n\t */\n\t\n\t'use strict';\n\t\n\t/**\n\t * Keeps track of the current owner.\n\t *\n\t * The current owner is the component who should own any components that are\n\t * currently being constructed.\n\t */\n\tvar ReactCurrentOwner = {\n\t\n\t /**\n\t * @internal\n\t * @type {ReactComponent}\n\t */\n\t current: null\n\t\n\t};\n\t\n\tmodule.exports = ReactCurrentOwner;\n\n/***/ },\n/* 14 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tmodule.exports = __webpack_require__(21);\n\n\n/***/ },\n/* 15 */\n/***/ function(module, exports) {\n\n\t/*\n\t\tMIT License http://www.opensource.org/licenses/mit-license.php\n\t\tAuthor Tobias Koppers @sokra\n\t*/\n\t// css base code, injected by the css-loader\n\tmodule.exports = function() {\n\t\tvar list = [];\n\t\n\t\t// return the list of modules as css string\n\t\tlist.toString = function toString() {\n\t\t\tvar result = [];\n\t\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\t\tvar item = this[i];\n\t\t\t\tif(item[2]) {\n\t\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\n\t\t\t\t} else {\n\t\t\t\t\tresult.push(item[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result.join(\"\");\n\t\t};\n\t\n\t\t// import a list of modules into the list\n\t\tlist.i = function(modules, mediaQuery) {\n\t\t\tif(typeof modules === \"string\")\n\t\t\t\tmodules = [[null, modules, \"\"]];\n\t\t\tvar alreadyImportedModules = {};\n\t\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\t\tvar id = this[i][0];\n\t\t\t\tif(typeof id === \"number\")\n\t\t\t\t\talreadyImportedModules[id] = true;\n\t\t\t}\n\t\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\t\tvar item = modules[i];\n\t\t\t\t// skip already imported module\n\t\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t\t// when a module is imported multiple times with different media queries.\n\t\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t\t}\n\t\t\t\t\tlist.push(item);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn list;\n\t};\n\n\n/***/ },\n/* 16 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/*\r\n\t\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\t\tAuthor Tobias Koppers @sokra\r\n\t*/\r\n\tvar stylesInDom = {},\r\n\t\tmemoize = function(fn) {\r\n\t\t\tvar memo;\r\n\t\t\treturn function () {\r\n\t\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\r\n\t\t\t\treturn memo;\r\n\t\t\t};\r\n\t\t},\r\n\t\tisOldIE = memoize(function() {\r\n\t\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\r\n\t\t}),\r\n\t\tgetHeadElement = memoize(function () {\r\n\t\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\r\n\t\t}),\r\n\t\tsingletonElement = null,\r\n\t\tsingletonCounter = 0,\r\n\t\tstyleElementsInsertedAtTop = [];\r\n\t\r\n\tmodule.exports = function(list, options) {\r\n\t\tif(false) {\r\n\t\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\r\n\t\t}\r\n\t\r\n\t\toptions = options || {};\r\n\t\t// Force single-tag solution on IE6-9, which has a hard limit on the # of + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +--> + + diff --git a/deploy/Git-Auto-Deploy/webui/scripts/build.js b/deploy/Git-Auto-Deploy/webui/scripts/build.js new file mode 100644 index 0000000..2c504ea --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/scripts/build.js @@ -0,0 +1,224 @@ +// Do this as the first thing so that any code reading it knows the right env. +process.env.NODE_ENV = 'production'; + +// Load environment variables from .env file. Suppress warnings using silent +// if this file is missing. dotenv will never modify any environment variables +// that have already been set. +// https://github.com/motdotla/dotenv +require('dotenv').config({silent: true}); + +var chalk = require('chalk'); +var fs = require('fs-extra'); +var path = require('path'); +var pathExists = require('path-exists'); +var filesize = require('filesize'); +var gzipSize = require('gzip-size').sync; +var webpack = require('webpack'); +var config = require('../config/webpack.config.prod'); +var paths = require('../config/paths'); +var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); +var recursive = require('recursive-readdir'); +var stripAnsi = require('strip-ansi'); + +var useYarn = pathExists.sync(paths.yarnLockFile); + +// Warn and crash if required files are missing +if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { + process.exit(1); +} + +// Input: /User/dan/app/build/static/js/main.82be8.js +// Output: /static/js/main.js +function removeFileNameHash(fileName) { + return fileName + .replace(paths.appBuild, '') + .replace(/\/?(.*)(\.\w+)(\.js|\.css)/, (match, p1, p2, p3) => p1 + p3); +} + +// Input: 1024, 2048 +// Output: "(+1 KB)" +function getDifferenceLabel(currentSize, previousSize) { + var FIFTY_KILOBYTES = 1024 * 50; + var difference = currentSize - previousSize; + var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0; + if (difference >= FIFTY_KILOBYTES) { + return chalk.red('+' + fileSize); + } else if (difference < FIFTY_KILOBYTES && difference > 0) { + return chalk.yellow('+' + fileSize); + } else if (difference < 0) { + return chalk.green(fileSize); + } else { + return ''; + } +} + +// First, read the current file sizes in build directory. +// This lets us display how much they changed later. +recursive(paths.appBuild, (err, fileNames) => { + var previousSizeMap = (fileNames || []) + .filter(fileName => /\.(js|css)$/.test(fileName)) + .reduce((memo, fileName) => { + var contents = fs.readFileSync(fileName); + var key = removeFileNameHash(fileName); + memo[key] = gzipSize(contents); + return memo; + }, {}); + + // Remove all content but keep the directory so that + // if you're in it, you don't end up in Trash + fs.emptyDirSync(paths.appBuild); + + // Start the webpack build + build(previousSizeMap); + + // Merge with the public folder + copyPublicFolder(); +}); + +// Print a detailed summary of build files. +function printFileSizes(stats, previousSizeMap) { + var assets = stats.toJson().assets + .filter(asset => /\.(js|css)$/.test(asset.name)) + .map(asset => { + var fileContents = fs.readFileSync(paths.appBuild + '/' + asset.name); + var size = gzipSize(fileContents); + var previousSize = previousSizeMap[removeFileNameHash(asset.name)]; + var difference = getDifferenceLabel(size, previousSize); + return { + folder: path.join('build', path.dirname(asset.name)), + name: path.basename(asset.name), + size: size, + sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : '') + }; + }); + assets.sort((a, b) => b.size - a.size); + var longestSizeLabelLength = Math.max.apply(null, + assets.map(a => stripAnsi(a.sizeLabel).length) + ); + assets.forEach(asset => { + var sizeLabel = asset.sizeLabel; + var sizeLength = stripAnsi(sizeLabel).length; + if (sizeLength < longestSizeLabelLength) { + var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength); + sizeLabel += rightPadding; + } + console.log( + ' ' + sizeLabel + + ' ' + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name) + ); + }); +} + +// Print out errors +function printErrors(summary, errors) { + console.log(chalk.red(summary)); + console.log(); + errors.forEach(err => { + console.log(err.message || err); + console.log(); + }); +} + +// Create the production build and print the deployment instructions. +function build(previousSizeMap) { + console.log('Creating an optimized production build...'); + webpack(config).run((err, stats) => { + if (err) { + printErrors('Failed to compile.', [err]); + process.exit(1); + } + + if (stats.compilation.errors.length) { + printErrors('Failed to compile.', stats.compilation.errors); + process.exit(1); + } + + if (process.env.CI && stats.compilation.warnings.length) { + printErrors('Failed to compile.', stats.compilation.warnings); + process.exit(1); + } + + console.log(chalk.green('Compiled successfully.')); + console.log(); + + console.log('File sizes after gzip:'); + console.log(); + printFileSizes(stats, previousSizeMap); + console.log(); + + var openCommand = process.platform === 'win32' ? 'start' : 'open'; + var appPackage = require(paths.appPackageJson); + var homepagePath = appPackage.homepage; + var publicPath = config.output.publicPath; + if (homepagePath && homepagePath.indexOf('.github.io/') !== -1) { + // "homepage": "http://user.github.io/project" + console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.'); + console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.'); + console.log(); + console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.'); + console.log('To publish it at ' + chalk.green(homepagePath) + ', run:'); + // If script deploy has been added to package.json, skip the instructions + if (typeof appPackage.scripts.deploy === 'undefined') { + console.log(); + if (useYarn) { + console.log(' ' + chalk.cyan('yarn') + ' add --dev gh-pages'); + } else { + console.log(' ' + chalk.cyan('npm') + ' install --save-dev gh-pages'); + } + console.log(); + console.log('Add the following script in your ' + chalk.cyan('package.json') + '.'); + console.log(); + console.log(' ' + chalk.dim('// ...')); + console.log(' ' + chalk.yellow('"scripts"') + ': {'); + console.log(' ' + chalk.dim('// ...')); + console.log(' ' + chalk.yellow('"deploy"') + ': ' + chalk.yellow('"npm run build&&gh-pages -d build"')); + console.log(' }'); + console.log(); + console.log('Then run:'); + } + console.log(); + console.log(' ' + chalk.cyan(useYarn ? 'yarn' : 'npm') + ' run deploy'); + console.log(); + } else if (publicPath !== '/') { + // "homepage": "http://mywebsite.com/project" + console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.'); + console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.'); + console.log(); + console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.'); + console.log(); + } else { + // no homepage or "homepage": "http://mywebsite.com" + console.log('The project was built assuming it is hosted at the server root.'); + if (homepagePath) { + // "homepage": "http://mywebsite.com" + console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.'); + console.log(); + } else { + // no homepage + console.log('To override this, specify the ' + chalk.green('homepage') + ' in your ' + chalk.cyan('package.json') + '.'); + console.log('For example, add this to build it for GitHub Pages:') + console.log(); + console.log(' ' + chalk.green('"homepage"') + chalk.cyan(': ') + chalk.green('"http://myname.github.io/myapp"') + chalk.cyan(',')); + console.log(); + } + console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.'); + console.log('You may also serve it locally with a static server:') + console.log(); + if (useYarn) { + console.log(' ' + chalk.cyan('yarn') + ' global add pushstate-server'); + } else { + console.log(' ' + chalk.cyan('npm') + ' install -g pushstate-server'); + } + console.log(' ' + chalk.cyan('pushstate-server') + ' build'); + console.log(' ' + chalk.cyan(openCommand) + ' http://localhost:9000'); + console.log(); + } + }); +} + +function copyPublicFolder() { + fs.copySync(paths.appPublic, paths.appBuild, { + dereference: true, + filter: file => file !== paths.appHtml + }); +} diff --git a/deploy/Git-Auto-Deploy/webui/scripts/start.js b/deploy/Git-Auto-Deploy/webui/scripts/start.js new file mode 100644 index 0000000..0b52c2f --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/scripts/start.js @@ -0,0 +1,315 @@ +process.env.NODE_ENV = 'development'; + +// Load environment variables from .env file. Suppress warnings using silent +// if this file is missing. dotenv will never modify any environment variables +// that have already been set. +// https://github.com/motdotla/dotenv +require('dotenv').config({silent: true}); + +var chalk = require('chalk'); +var webpack = require('webpack'); +var WebpackDevServer = require('webpack-dev-server'); +var historyApiFallback = require('connect-history-api-fallback'); +var httpProxyMiddleware = require('http-proxy-middleware'); +var detect = require('detect-port'); +var clearConsole = require('react-dev-utils/clearConsole'); +var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); +var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); +var getProcessForPort = require('react-dev-utils/getProcessForPort'); +var openBrowser = require('react-dev-utils/openBrowser'); +var prompt = require('react-dev-utils/prompt'); +var pathExists = require('path-exists'); +var config = require('../config/webpack.config.dev'); +var paths = require('../config/paths'); + +var useYarn = pathExists.sync(paths.yarnLockFile); +var cli = useYarn ? 'yarn' : 'npm'; +var isInteractive = process.stdout.isTTY; + +// Warn and crash if required files are missing +if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { + process.exit(1); +} + +// Tools like Cloud9 rely on this. +var DEFAULT_PORT = process.env.PORT || 3000; +var compiler; +var handleCompile; + +// You can safely remove this after ejecting. +// We only use this block for testing of Create React App itself: +var isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1); +if (isSmokeTest) { + handleCompile = function (err, stats) { + if (err || stats.hasErrors() || stats.hasWarnings()) { + process.exit(1); + } else { + process.exit(0); + } + }; +} + +function setupCompiler(host, port, protocol) { + // "Compiler" is a low-level interface to Webpack. + // It lets us listen to some events and provide our own custom messages. + compiler = webpack(config, handleCompile); + + // "invalid" event fires when you have changed a file, and Webpack is + // recompiling a bundle. WebpackDevServer takes care to pause serving the + // bundle, so if you refresh, it'll wait instead of serving the old one. + // "invalid" is short for "bundle invalidated", it doesn't imply any errors. + compiler.plugin('invalid', function() { + if (isInteractive) { + clearConsole(); + } + console.log('Compiling...'); + }); + + var isFirstCompile = true; + + // "done" event fires when Webpack has finished recompiling the bundle. + // Whether or not you have warnings or errors, you will get this event. + compiler.plugin('done', function(stats) { + if (isInteractive) { + clearConsole(); + } + + // We have switched off the default Webpack output in WebpackDevServer + // options so we are going to "massage" the warnings and errors and present + // them in a readable focused way. + var messages = formatWebpackMessages(stats.toJson({}, true)); + var isSuccessful = !messages.errors.length && !messages.warnings.length; + var showInstructions = isSuccessful && (isInteractive || isFirstCompile); + + if (isSuccessful) { + console.log(chalk.green('Compiled successfully!')); + } + + if (showInstructions) { + console.log(); + console.log('The app is running at:'); + console.log(); + console.log(' ' + chalk.cyan(protocol + '://' + host + ':' + port + '/')); + console.log(); + console.log('Note that the development build is not optimized.'); + console.log('To create a production build, use ' + chalk.cyan(cli + ' run build') + '.'); + console.log(); + isFirstCompile = false; + } + + // If errors exist, only show errors. + if (messages.errors.length) { + console.log(chalk.red('Failed to compile.')); + console.log(); + messages.errors.forEach(message => { + console.log(message); + console.log(); + }); + return; + } + + // Show warnings if no errors were found. + if (messages.warnings.length) { + console.log(chalk.yellow('Compiled with warnings.')); + console.log(); + messages.warnings.forEach(message => { + console.log(message); + console.log(); + }); + // Teach some ESLint tricks. + console.log('You may use special comments to disable some warnings.'); + console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.'); + console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.'); + } + }); +} + +// We need to provide a custom onError function for httpProxyMiddleware. +// It allows us to log custom error messages on the console. +function onProxyError(proxy) { + return function(err, req, res){ + var host = req.headers && req.headers.host; + console.log( + chalk.red('Proxy error:') + ' Could not proxy request ' + chalk.cyan(req.url) + + ' from ' + chalk.cyan(host) + ' to ' + chalk.cyan(proxy) + '.' + ); + console.log( + 'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' + + chalk.cyan(err.code) + ').' + ); + console.log(); + + // And immediately send the proper error response to the client. + // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side. + if (res.writeHead && !res.headersSent) { + res.writeHead(500); + } + res.end('Proxy error: Could not proxy request ' + req.url + ' from ' + + host + ' to ' + proxy + ' (' + err.code + ').' + ); + } +} + +function addMiddleware(devServer) { + // `proxy` lets you to specify a fallback server during development. + // Every unrecognized request will be forwarded to it. + var proxy = require(paths.appPackageJson).proxy; + devServer.use(historyApiFallback({ + // Paths with dots should still use the history fallback. + // See https://github.com/facebookincubator/create-react-app/issues/387. + disableDotRule: true, + // For single page apps, we generally want to fallback to /index.html. + // However we also want to respect `proxy` for API calls. + // So if `proxy` is specified, we need to decide which fallback to use. + // We use a heuristic: if request `accept`s text/html, we pick /index.html. + // Modern browsers include text/html into `accept` header when navigating. + // However API calls like `fetch()` won’t generally accept text/html. + // If this heuristic doesn’t work well for you, don’t use `proxy`. + htmlAcceptHeaders: proxy ? + ['text/html'] : + ['text/html', '*/*'] + })); + if (proxy) { + if (typeof proxy !== 'string') { + console.log(chalk.red('When specified, "proxy" in package.json must be a string.')); + console.log(chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".')); + console.log(chalk.red('Either remove "proxy" from package.json, or make it a string.')); + process.exit(1); + } + + // Otherwise, if proxy is specified, we will let it handle any request. + // There are a few exceptions which we won't send to the proxy: + // - /index.html (served as HTML5 history API fallback) + // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading) + // - /sockjs-node/* (WebpackDevServer uses this for hot reloading) + // Tip: use https://jex.im/regulex/ to visualize the regex + var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/; + + // Pass the scope regex both to Express and to the middleware for proxying + // of both HTTP and WebSockets to work without false positives. + var hpm = httpProxyMiddleware(pathname => mayProxy.test(pathname), { + target: proxy, + logLevel: 'silent', + onProxyReq: function(proxyReq, req, res) { + // Browers may send Origin headers even with same-origin + // requests. To prevent CORS issues, we have to change + // the Origin to match the target URL. + if (proxyReq.getHeader('origin')) { + proxyReq.setHeader('origin', proxy); + } + }, + onError: onProxyError(proxy), + secure: false, + changeOrigin: true, + ws: true + }); + devServer.use(mayProxy, hpm); + + // Listen for the websocket 'upgrade' event and upgrade the connection. + // If this is not done, httpProxyMiddleware will not try to upgrade until + // an initial plain HTTP request is made. + devServer.listeningApp.on('upgrade', hpm.upgrade); + } + + // Finally, by now we have certainly resolved the URL. + // It may be /index.html, so let the dev server try serving it again. + devServer.use(devServer.middleware); +} + +function runDevServer(host, port, protocol) { + var devServer = new WebpackDevServer(compiler, { + // Enable gzip compression of generated files. + compress: true, + // Silence WebpackDevServer's own logs since they're generally not useful. + // It will still show compile warnings and errors with this setting. + clientLogLevel: 'none', + // By default WebpackDevServer serves physical files from current directory + // in addition to all the virtual build products that it serves from memory. + // This is confusing because those files won’t automatically be available in + // production build folder unless we copy them. However, copying the whole + // project directory is dangerous because we may expose sensitive files. + // Instead, we establish a convention that only files in `public` directory + // get served. Our build script will copy `public` into the `build` folder. + // In `index.html`, you can get URL of `public` folder with %PUBLIC_PATH%: + // + // In JavaScript code, you can access it with `process.env.PUBLIC_URL`. + // Note that we only recommend to use `public` folder as an escape hatch + // for files like `favicon.ico`, `manifest.json`, and libraries that are + // for some reason broken when imported through Webpack. If you just want to + // use an image, put it in `src` and `import` it from JavaScript instead. + contentBase: paths.appPublic, + // Enable hot reloading server. It will provide /sockjs-node/ endpoint + // for the WebpackDevServer client so it can learn when the files were + // updated. The WebpackDevServer client is included as an entry point + // in the Webpack development configuration. Note that only changes + // to CSS are currently hot reloaded. JS changes will refresh the browser. + hot: true, + // It is important to tell WebpackDevServer to use the same "root" path + // as we specified in the config. In development, we always serve from /. + publicPath: config.output.publicPath, + // WebpackDevServer is noisy by default so we emit custom message instead + // by listening to the compiler events with `compiler.plugin` calls above. + quiet: true, + // Reportedly, this avoids CPU overload on some systems. + // https://github.com/facebookincubator/create-react-app/issues/293 + watchOptions: { + ignored: /node_modules/ + }, + // Enable HTTPS if the HTTPS environment variable is set to 'true' + https: protocol === "https", + host: host + }); + + // Our custom middleware proxies requests to /index.html or a remote API. + addMiddleware(devServer); + + // Launch WebpackDevServer. + devServer.listen(port, (err, result) => { + if (err) { + return console.log(err); + } + + if (isInteractive) { + clearConsole(); + } + console.log(chalk.cyan('Starting the development server...')); + console.log(); + + if (isInteractive) { + openBrowser(protocol + '://' + host + ':' + port + '/'); + } + }); +} + +function run(port) { + var protocol = process.env.HTTPS === 'true' ? "https" : "http"; + var host = process.env.HOST || 'localhost'; + setupCompiler(host, port, protocol); + runDevServer(host, port, protocol); +} + +// We attempt to use the default port but if it is busy, we offer the user to +// run on a different port. `detect()` Promise resolves to the next free port. +detect(DEFAULT_PORT).then(port => { + if (port === DEFAULT_PORT) { + run(port); + return; + } + + if (isInteractive) { + clearConsole(); + var existingProcess = getProcessForPort(DEFAULT_PORT); + var question = + chalk.yellow('Something is already running on port ' + DEFAULT_PORT + '.' + + ((existingProcess) ? ' Probably:\n ' + existingProcess : '')) + + '\n\nWould you like to run the app on another port instead?'; + + prompt(question, true).then(shouldChangePort => { + if (shouldChangePort) { + run(port); + } + }); + } else { + console.log(chalk.red('Something is already running on port ' + DEFAULT_PORT + '.')); + } +}); diff --git a/deploy/Git-Auto-Deploy/webui/scripts/test.js b/deploy/Git-Auto-Deploy/webui/scripts/test.js new file mode 100644 index 0000000..c4dc347 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/scripts/test.js @@ -0,0 +1,31 @@ +process.env.NODE_ENV = 'test'; +process.env.PUBLIC_URL = ''; + +// Load environment variables from .env file. Suppress warnings using silent +// if this file is missing. dotenv will never modify any environment variables +// that have already been set. +// https://github.com/motdotla/dotenv +require('dotenv').config({silent: true}); + +const jest = require('jest'); +const argv = process.argv.slice(2); + +// Watch unless on CI or in coverage mode +if (!process.env.CI && argv.indexOf('--coverage') < 0) { + argv.push('--watch'); +} + +// A temporary hack to clear terminal correctly. +// You can remove this after updating to Jest 18 when it's out. +// https://github.com/facebook/jest/pull/2230 +var realWrite = process.stdout.write; +var CLEAR = process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'; +process.stdout.write = function(chunk, encoding, callback) { + if (chunk === '\x1B[2J\x1B[H') { + chunk = CLEAR; + } + return realWrite.call(this, chunk, encoding, callback); +}; + + +jest.run(argv); diff --git a/deploy/Git-Auto-Deploy/webui/src/App.js b/deploy/Git-Auto-Deploy/webui/src/App.js new file mode 100644 index 0000000..caaee72 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/App.js @@ -0,0 +1,26 @@ +import React, { Component } from 'react'; +import './App.scss'; +import Timeline from './Timeline'; +import Navigation from './Navigation'; + +class App extends Component { + render() { +/* + if(window.location.protocol !== "https:" && process.env.NODE_ENV !== 'development') { + return ( +
+
The Web UI is not available over HTTP. To use it; enable SSL, restart GAD and browse to this page using HTTPS.
+
+ ); + } +*/ + return ( +
+ + +
+ ); + } +} + +export default App; diff --git a/deploy/Git-Auto-Deploy/webui/src/App.test.js b/deploy/Git-Auto-Deploy/webui/src/App.test.js new file mode 100644 index 0000000..b84af98 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/App.test.js @@ -0,0 +1,8 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); +}); diff --git a/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/DateNode.js b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/DateNode.js new file mode 100644 index 0000000..a8013f0 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/DateNode.js @@ -0,0 +1,16 @@ +import React, { Component } from 'react'; +import './DateNode.scss'; + +class DateNode extends Component { + + render() { + return ( +
+ +

{this.props.date}

+
+ ); + } +} + +export default DateNode; diff --git a/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EndNode.js b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EndNode.js new file mode 100644 index 0000000..6844b40 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EndNode.js @@ -0,0 +1,16 @@ +import React, { Component } from 'react'; +import './EndNode.scss'; + +class EndNode extends Component { + + render() { + return ( +
+ +

{this.props.date}

+
+ ); + } +} + +export default EndNode; diff --git a/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EventMessages.js b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EventMessages.js new file mode 100644 index 0000000..b3a277f --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EventMessages.js @@ -0,0 +1,31 @@ +import React, { Component } from 'react'; +import './EventMessages.scss'; + +class EventMessages extends Component { + + getMessages() { + + var messages = this.props.event.messages; + + if(!messages) + return; + + var elements = []; + + for(var i = messages.length - 1; i >= 0; i--) { + elements.push(

{messages[i]}

); + } + + return elements; + } + + render() { + return ( +
+ {this.getMessages()} +
+ ); + } +} + +export default EventMessages; diff --git a/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EventNode.js b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EventNode.js new file mode 100644 index 0000000..74022a7 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Components/Timeline/EventNode.js @@ -0,0 +1,42 @@ +import React, { Component } from 'react'; +import './EventNode.scss'; + +class EventNode extends Component { + + getIconElement() { + + if(this.props.event.isWaiting()) { + return ( +
+ ); + } + + return ( + + ); + } + + render() { + return ( +
+ + +
+
+ {this.getIconElement()} +

{this.props.event.getTitle()}

+

{this.props.event.getSubtitle()}

+
+
+ {this.props.children} +
+ + + +
+
+ ); + } +} + +export default EventNode; diff --git a/deploy/Git-Auto-Deploy/webui/src/Components/WebSocketStatus.js b/deploy/Git-Auto-Deploy/webui/src/Components/WebSocketStatus.js new file mode 100644 index 0000000..8c134f8 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Components/WebSocketStatus.js @@ -0,0 +1,32 @@ +import React, { Component } from 'react'; +import './WebSocketStatus.scss'; + +class WebSocketStatus extends Component { + render() { + + if(this.props.wsIsOpen && !this.props.wsIsAuthenticated) + return ( +
+ Authenticating against {this.props.wsURI} +
+ ); + + if(this.props.wsIsRecovering) + return ( +
+ Reconnecting to {this.props.wsURI} +
+ ); + + if(this.props.wsIsOpen) + return ( +
+ Receiving real time updates from {this.props.wsURI} +
+ ); + + return null; + } +} + +export default WebSocketStatus; diff --git a/deploy/Git-Auto-Deploy/webui/src/Event.js b/deploy/Git-Auto-Deploy/webui/src/Event.js new file mode 100644 index 0000000..f5a2dd2 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Event.js @@ -0,0 +1,91 @@ +import moment from 'moment'; + +class Event { + + constructor(event) { + var self = this; + self.event = event; + + for(var key in event) { + if(!event.hasOwnProperty(key)) + continue; + self[key] = event[key]; + } + } + + getColorClass() { + + if(this.event.type === "StartupEvent") + return "green"; + + if(this.event.type === "WebhookAction") + return "blue"; + + if(this.event.type === "DeployEvent") + return "blue"; + + return "blue"; +// return "purple"; + } + + getTitle() { + + if(this.event.type === "StartupEvent") + return "Startup"; + + if(this.event.type === "WebhookAction") + return "Webhook"; + + if(this.event.type === "DeployEvent") + return "Deploy"; + + return this.event.type; + } + + getSubtitle() { + + if(this.event.type === "StartupEvent") { + + if(this.isWaiting()) + return "Starting up.." + + return "Listening for incoming connections"; + } + + if(this.event.type === "WebhookAction") { + if(this.event.messages.length) + return this.event.messages[this.event.messages.length - 1] + return "Incoming request from " + this.event['client-address']; + } + + if(this.event.type === "DeployEvent") + return this.event.name; + + return this.event.type; + } + + getDate() { + return moment.unix(this.event.timestamp).format("YYYY-MM-DD"); + } + + getTime() { + return moment.unix(this.event.timestamp).format("HH:mm"); + } + + getIconName() { + + if(this.event.success === false) + return "alert" + + if(this.event.type === "StartupEvent") + return "alert-circle"; + + return "check"; + } + + isWaiting() { + return this.event.waiting; + } +} + +export default Event; diff --git a/deploy/Git-Auto-Deploy/webui/src/Navigation.js b/deploy/Git-Auto-Deploy/webui/src/Navigation.js new file mode 100644 index 0000000..4785ebc --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Navigation.js @@ -0,0 +1,14 @@ +import React, { Component } from 'react'; +import './Navigation.scss'; + +class Navigation extends Component { + render() { + return ( +
+

Git-Auto-Deploy

+
+ ); + } +} + +export default Navigation; diff --git a/deploy/Git-Auto-Deploy/webui/src/Timeline.js b/deploy/Git-Auto-Deploy/webui/src/Timeline.js new file mode 100644 index 0000000..868e531 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/Timeline.js @@ -0,0 +1,403 @@ +import React, { Component } from 'react'; +import './Timeline.scss'; +import axios from 'axios'; +import Event from './Event'; +import EventNode from './Components/Timeline/EventNode'; +import DateNode from './Components/Timeline/DateNode'; +import EndNode from './Components/Timeline/EndNode'; +import EventMessages from './Components/Timeline/EventMessages'; +import moment from 'moment'; +import WebSocketStatus from './Components/WebSocketStatus'; + +class Timeline extends Component { + constructor(props) { + super(props); + + var host = window.location.protocol + '//' + window.location.host; + + if (process.env.NODE_ENV === 'development') { + host = 'https://10.0.0.1:8002'; + } + + this.state = { + events: [], + loaded: false, + error: false, + wsIsOpen: false, + wsIsAuthenticated: false, + wsIsRecovering: false, + wsURI: null, + wsAuthKey: null, + host: host + }; + + this.wsSocket = null; + + var self = this; + + setInterval(function() { + self.recover(); + }, 5000); + } + + componentDidMount() { + this.fetchEventList(); + this.initUserNotification(); + } + + initUserNotification() { + if(!('Notification' in window)) + return; + + // Not yet approved? + if (Notification.permission === 'default') { + + // Request permission + return Notification.requestPermission(function() { + //console.log("Got permission!"); + }); + } + } + + showUserNotification(event) { + + if(!('Notification' in window)) + return; + + if(Notification.permission !== "granted") + return; + + // define new notification + var n = new Notification( + event.getSubtitle(), + { + 'body': event.getTitle(), + 'tag' : "event-" + event.id + } + ); + + // notify when shown successfull + n.onshow = function () { + console.log("onshow"); + }; + + // remove the notification from Notification Center when clicked. + n.onclick = function () { + this.close(); + console.log("onclick"); + }; + + // callback function when the notification is closed. + n.onclose = function () { + console.log("onclose"); + }; + + // notification cannot be presented to the user, this event is fired if the permission level is set to denied or default. + n.onerror = function () { + console.log("onerror"); + }; + } + + recover() { + var self = this; + + if(!self.state.wsIsOpen) { + self.initWebsocketConnection(self.state.wsURI); + return; + } + + if(!self.state.wsIsAuthenticated) { + self.authenticateWebsocketConnection(); + return; + } + + } + + fetchEventList() { + + var self = this; + + axios.get(this.state.host + '/api/status') + .then(function(res) { + const events = res.data.events.map(obj => new Event(obj)); + + const wsURI = res.data['wss-uri'] === undefined ? null : res.data['wss-uri']; + + self.setState({ + events: events, + loaded: true, + error: false, + wsURI: wsURI, + wsAuthKey: res.data['auth-key'] + }); + + // Once we get to know the web socket port, we can make the web socket connection + if(wsURI && !self.state.wsIsRecovering) { + self.initWebsocketConnection(res.data['wss-uri']); + } + + }) + .catch(err => { + console.warn(err); + this.setState({ + loaded: true, + error: true + }); + }); + + } + + addOrUpdateEvent(event) { + + this.setState((prevState, props) => { + + var newEvents = []; + var inserted = false; + + for(var key in prevState.events) { + if(prevState.hasOwnProperty(key)) + continue; + var curEvent = prevState.events[key]; + + if(curEvent.id === event.id) { + newEvents.push(event); + inserted = true; + } else { + newEvents.push(curEvent); + } + } + + if(!inserted) { + newEvents.push(event); + } + + return { + events: newEvents + } + + }); + } + + getEventWithId(id) { + var self = this; + + for(var key in self.state.events) { + + if(self.state.hasOwnProperty(key)) + continue; + + var event = self.state.events[key]; + + if(event.id === id) + return event; + + } + + return undefined; + } + + authenticateWebsocketConnection(authKey) { + var self = this; + + // Authenticate + self.wsSocket.send(JSON.stringify({ + "type": "authenticate", + "auth-key": self.state.wsAuthKey + })); + } + + handleJSONMessage(data) { + var event; + var self = this; + + // Auth key was invalid, maybe the server restarted + if(data.type === "bad-auth-key") { + + self.setState({ + wsIsAuthenticated: false, + wsIsRecovering: true + }); + + // Get a fresh auth key + self.fetchEventList(); + + } else if(data.type === "authenticated") { + + if(self.state.wsIsRecovering) { + self.fetchEventList(); + } + + self.setState({ + wsIsAuthenticated: true, + wsIsRecovering: false + }); + + } else if(data.type === "new-event") { + + event = new Event(data.event); + this.addOrUpdateEvent(event); + + } else if(data.type === "event-updated") { + + event = new Event(data.event); + this.addOrUpdateEvent(event); + + } else if(data.type === "event-success") { + + event = this.getEventWithId(data.id); + + if(event && event.type === "WebhookAction") { + this.showUserNotification(event); + } + + } else { + console.log("Unknown event: " + data.type); + } + } + + initWebsocketConnection(uri) { + var self = this; + + if(!uri) + return; + + self.wsSocket = new WebSocket(uri); + self.wsSocket.binaryType = "arraybuffer"; + self.wsSocket.onopen = function() { + + self.setState({ + wsIsOpen: true, + }); + + self.authenticateWebsocketConnection(); + + }; + + self.wsSocket.onmessage = (e) => { + if (typeof e.data === "string") { + try { + var data = JSON.parse(e.data); + self.handleJSONMessage(data); + } catch(e) { + console.error(e); + } + } else { + var arr = new Uint8Array(e.data); + var hex = ''; + for (var i = 0; i < arr.length; i++) { + hex += ('00' + arr[i].toString(16)).substr(-2); + } + console.log("Binary message received: " + hex); + } + }; + + self.wsSocket.onclose = function() { + + self.wsSocket.close(); + self.wsSocket = null; + + self.setState({ + wsIsOpen: false, + wsIsRecovering: true + }); + + if(self.wsReconnectTimeout !== undefined) { + clearTimeout(self.wsReconnectTimeout); + } + + // Try to reconnect again after 2 seconds + self.wsReconnectTimeout = setTimeout(function() { + + self.initWebsocketConnection(uri); + self.wsReconnectTimeout = undefined; + }, 2000); + }; + } + + /* + function sendText() { + if (isopen) { + socket.send("Hello, world!"); + console.log("Text message sent."); + } else { + console.log("Connection not opened.") + } + }; + function sendBinary() { + if (isopen) { + var buf = new ArrayBuffer(32); + var arr = new Uint8Array(buf); + for (i = 0; i < arr.length; ++i) arr[i] = i; + socket.send(buf); + console.log("Binary message sent."); + } else { + console.log("Connection not opened.") + } + }; + */ + + getDate(timestamp) { + return moment.unix(timestamp).format("YYYY-MM-DD"); + } + + getTimelineObjects() { + var rows = []; + var last_date = ''; + var events = this.state.events; + + rows.push(); + + for (var i=events.length-1; i >= 0; i--) { + var event = events[i]; + + rows.push( + + ); + + var cur_date = this.getDate(event.timestamp); + var next_date = ""; + if(i > 0) + next_date = this.getDate(events[i-1].timestamp); + + if(next_date === cur_date) + continue; + + if(cur_date !== last_date) { + rows.push(); + last_date = cur_date; + } + } + + return rows; + } + + render() { + + if(!this.state.loaded) { + return ( +
+
Connecting to {this.state.host}..
+
+ ); + } + + if(this.state.error) { + return ( +
+
Unable to connect to {this.state.host}
+
+ ); + } + + return ( +
+
+ {this.getTimelineObjects()} +
+ +
+ ); + } +} + +export default Timeline; diff --git a/deploy/Git-Auto-Deploy/webui/src/index.css b/deploy/Git-Auto-Deploy/webui/src/index.css new file mode 100644 index 0000000..3a4e5f9 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/index.css @@ -0,0 +1,10 @@ +html, +body { + height: 100%; + margin: 0; + padding: 0; +} + +body { + background: #f2f2f2; +} diff --git a/deploy/Git-Auto-Deploy/webui/src/index.js b/deploy/Git-Auto-Deploy/webui/src/index.js new file mode 100644 index 0000000..54c5ef1 --- /dev/null +++ b/deploy/Git-Auto-Deploy/webui/src/index.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; +import './index.css'; + +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/GitAutoDeploy.conf.json b/deploy/GitAutoDeploy.conf.json similarity index 78% rename from GitAutoDeploy.conf.json rename to deploy/GitAutoDeploy.conf.json index 165943a..48e1ecb 100644 --- a/GitAutoDeploy.conf.json +++ b/deploy/GitAutoDeploy.conf.json @@ -4,7 +4,7 @@ [{ "url": "https://git.elab.kth.se/davide/ELAB-partsearch", "path": "/srv/ELAB-partsearch", - "deploy": "echo Deploying and restarting ELAB-partsearch && git reset --hard && git pull", + "deploy": "echo Deploying and restarting ELAB-partsearch && git reset --hard && git pull && sudo /usr/local/sbin/restart_partsearch.sh", "secret-token": "etaeZee5eedie7sah8shaigo" }] } diff --git a/deploy/restart_partsearch.sh b/deploy/restart_partsearch.sh new file mode 100755 index 0000000..0e74b6f --- /dev/null +++ b/deploy/restart_partsearch.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sudo supervisorctl restart partsearch